feat: migrate workspace worker and companion domains to ServerApi
This commit is contained in:
@@ -1,30 +1,36 @@
|
||||
// Generated by `cargo run -p server-api --features typescript --example generate_companion_api_types`.
|
||||
// Do not edit manually.
|
||||
// @generated by yoi-companion-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:550383b600fe2a2e55630849c7de7a6a24463ad41d0c18dc5d254a3d14328f07)
|
||||
// Options: companion-operation-schema-closure,openapi-3.1,strict-integer-ranges,sorted-output
|
||||
// Output: web/workspace/src/lib/generated/companion-api.ts
|
||||
// Regenerate/check: cargo run -q -p server-api --example generate_companion_api_types -- --check
|
||||
|
||||
export type DiagnosticSeverity = "info" | "warning" | "error";
|
||||
|
||||
export type Diagnostic = { code: string, severity: DiagnosticSeverity, message: string, };
|
||||
|
||||
export type WorkspaceWorkerSubject = { "kind": "runtime_worker", runtime_id: string, worker_id: string, };
|
||||
|
||||
export type WorkspaceWorkerDiscoveryItem = { subject: WorkspaceWorkerSubject, resource_key: string, display_name: string, profile: string | null, status?: string | null, };
|
||||
export type CompanionCancelRequest = { reason?: string | null; };
|
||||
|
||||
export type CompanionLifecycleState = "idle" | "running" | "stopped";
|
||||
|
||||
export type CompanionMessageDisposition = "accepted" | "rejected";
|
||||
|
||||
export type CompanionTransportSummary = { mode: string, available: boolean, };
|
||||
export type CompanionMessageRequest = { content: string; };
|
||||
|
||||
export type CompanionStatusResponse = { state: CompanionLifecycleState, worker: WorkspaceWorkerDiscoveryItem | null, transport: CompanionTransportSummary, diagnostics: Array<Diagnostic>, };
|
||||
export type CompanionMessageResponse = { message: string; state: CompanionMessageDisposition; };
|
||||
|
||||
export type CompanionMessageRequest = { content: string, };
|
||||
export type CompanionStatusResponse = { diagnostics?: Array<Diagnostic>; state: CompanionLifecycleState; transport: CompanionTransportSummary; worker?: WorkspaceWorkerDiscoveryItem | null; };
|
||||
|
||||
export type CompanionCancelRequest = { reason?: string | null, };
|
||||
export type CompanionTranscriptItem = { content: string; created_at: string; role: CompanionTranscriptRole; sequence: number; };
|
||||
|
||||
export type CompanionMessageResponse = { state: CompanionMessageDisposition, message: string, };
|
||||
export type CompanionTranscriptProjection = { items: Array<CompanionTranscriptItem>; limit: number; next?: number | null; start: number; state: CompanionLifecycleState; total: number; };
|
||||
|
||||
export type CompanionTranscriptRole = "user" | "assistant";
|
||||
|
||||
export type CompanionTranscriptItem = { sequence: number, role: CompanionTranscriptRole, content: string, created_at: string, };
|
||||
export type CompanionTransportSummary = { available: boolean; mode: string; };
|
||||
|
||||
export type CompanionTranscriptProjection = { state: CompanionLifecycleState, start: number, limit: number, total: number, next: number | null, items: Array<CompanionTranscriptItem>, };
|
||||
export type Diagnostic = { code: string; message: string; severity: DiagnosticSeverity; };
|
||||
|
||||
export type DiagnosticSeverity = "info" | "warning" | "error";
|
||||
|
||||
export type RepositoryApiError = { diagnostics?: Array<Diagnostic>; error: string; message: string; };
|
||||
|
||||
export type WorkspaceWorkerDiscoveryItem = { display_name: string; profile?: string | null; resource_key: string; status?: string | null; subject: WorkspaceWorkerSubject; };
|
||||
|
||||
export type WorkspaceWorkerSubject = { kind: "runtime_worker"; runtime_id: string; worker_id: string; };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @generated by yoi-repository-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:67e56d1ffd3b27bc8653ef791bd68b5150ac7d507ccbe4e65b2e00320834d718)
|
||||
// Input contract: 0.1.0 (sha256:550383b600fe2a2e55630849c7de7a6a24463ad41d0c18dc5d254a3d14328f07)
|
||||
// Options: repository-operation-schema-closure,openapi-3.1,format:uint64=safe-number,strict-safe-integers,sorted-output
|
||||
// Output: web/workspace/src/lib/generated/repository-api.ts
|
||||
// Regenerate/check: cargo run -q -p server-api --example generate_repository_openapi_types -- --check
|
||||
@@ -55,11 +55,21 @@ export type RepositorySshHostTrust = { created_at: string; current_revision: num
|
||||
|
||||
export type RepositorySummary = { default_selector?: string | null; diagnostics?: Array<RepositoryDiagnostic> | null; git?: GitRepositorySummary | null; kind: string; observed_at?: string | null; observed_status: RepositoryObservedStatus; provider: string; record_authority: string; repository_key: string; source: RepositorySource; source_fingerprint: string; source_revision: number; };
|
||||
|
||||
export type WorkerBusyState = { kind: "run"; state: WorkerRunState; } | { kind: "maintenance"; state: WorkerMaintenanceState; };
|
||||
|
||||
export type WorkerCapabilitySummary = { can_spawn_followup: boolean; can_stop: boolean; };
|
||||
|
||||
export type WorkerImplementationSummary = { display_hint: string; kind: string; };
|
||||
|
||||
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: unknown; workspace: WorkerWorkspaceSummary; };
|
||||
export type WorkerMaintenanceState = "compacting";
|
||||
|
||||
export type WorkerRunState = "running" | "pausing" | "paused" | "cancelling";
|
||||
|
||||
export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyState; };
|
||||
|
||||
export type WorkerStateSnapshot = { last_command_id: number; state: WorkerState; };
|
||||
|
||||
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: WorkerStateSnapshot | null; workspace: WorkerWorkspaceSummary; };
|
||||
|
||||
export type WorkerWorkdirAttachmentSummary = { alias: string; working_directory: WorkingDirectorySummary; };
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @generated by yoi-runtime-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:67e56d1ffd3b27bc8653ef791bd68b5150ac7d507ccbe4e65b2e00320834d718)
|
||||
// Input contract: 0.1.0 (sha256:550383b600fe2a2e55630849c7de7a6a24463ad41d0c18dc5d254a3d14328f07)
|
||||
// Options: runtime-operation-schema-closure,openapi-3.1,strict-integer-ranges,sorted-output
|
||||
// Output: web/workspace/src/lib/generated/runtime-api.ts
|
||||
// Regenerate/check: cargo run -q -p server-api --example generate_runtime_api_types -- --check
|
||||
@@ -105,11 +105,11 @@ export type RuntimeWorkerLifecycleResult = { diagnostics?: Array<Diagnostic>; ru
|
||||
|
||||
export type RuntimeWorkerListResponse = { diagnostics?: Array<Diagnostic>; items: Array<WorkerSummary>; limit: number; source: string; workspace_id: string; };
|
||||
|
||||
export type RuntimeWorkerShowResponse = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; updated_at: string; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: unknown; workspace: WorkerWorkspaceSummary; };
|
||||
export type RuntimeWorkerShowResponse = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; updated_at: string; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: WorkerStateSnapshot | null; workspace: WorkerWorkspaceSummary; };
|
||||
|
||||
export type RuntimeWorkerSpawnAcceptanceEvidence = { detail: string; kind: string; };
|
||||
|
||||
export type RuntimeWorkerSpawnAcceptanceRequirement = "socket_ready" | { run_accepted: { expected_segments: number; }; };
|
||||
export type RuntimeWorkerSpawnAcceptanceRequirement = { kind: "socket_ready"; } | { expected_segments: number; kind: "run_accepted"; };
|
||||
|
||||
export type RuntimeWorkerSpawnIntent = { kind: "workspace_companion"; } | { kind: "workspace_orchestrator"; } | { kind: "workspace_coding"; } | { kind: "ticket_role"; role: RuntimeTicketWorkerRole; ticket_id: string; };
|
||||
|
||||
@@ -127,12 +127,16 @@ export type RuntimeWorkerTicketAssignmentRequest = { operation_id: string; ticke
|
||||
|
||||
export type UpdateRemoteRuntimeRequest = { display_name?: string | null; endpoint: string; };
|
||||
|
||||
export type WorkerBusyState = { kind: "run"; state: WorkerRunState; } | { kind: "maintenance"; state: WorkerMaintenanceState; };
|
||||
|
||||
export type WorkerCapabilitySummary = { can_spawn_followup: boolean; can_stop: boolean; };
|
||||
|
||||
export type WorkerFileDeleteResponse = { deleted: boolean; };
|
||||
|
||||
export type WorkerImplementationSummary = { display_hint: string; kind: string; };
|
||||
|
||||
export type WorkerMaintenanceState = "compacting";
|
||||
|
||||
export type WorkerOperationState = "accepted" | "unsupported" | "rejected";
|
||||
|
||||
export type WorkerRestoreResponse = { result: WorkerRestoreResult; runtime_id: string; worker_id: string; workspace_id: string; };
|
||||
@@ -143,7 +147,13 @@ export type WorkerRestoreState = "accepted" | "rejected" | "rolled_back" | "reco
|
||||
|
||||
export type WorkerRetentionResponse = { pinned: boolean; retention_state: string; runtime_id: string; worker_id: string; workspace_id: string; };
|
||||
|
||||
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: unknown; workspace: WorkerWorkspaceSummary; };
|
||||
export type WorkerRunState = "running" | "pausing" | "paused" | "cancelling";
|
||||
|
||||
export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyState; };
|
||||
|
||||
export type WorkerStateSnapshot = { last_command_id: number; state: WorkerState; };
|
||||
|
||||
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: WorkerStateSnapshot | null; workspace: WorkerWorkspaceSummary; };
|
||||
|
||||
export type WorkerWorkdirAttachmentSummary = { alias: string; working_directory: WorkingDirectorySummary; };
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @generated by yoi-workdir-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:67e56d1ffd3b27bc8653ef791bd68b5150ac7d507ccbe4e65b2e00320834d718)
|
||||
// Input contract: 0.1.0 (sha256:550383b600fe2a2e55630849c7de7a6a24463ad41d0c18dc5d254a3d14328f07)
|
||||
// Options: workdir-operation-schema-closure,openapi-3.1,strict-integer-ranges,sorted-output
|
||||
// Output: web/workspace/src/lib/generated/workdir-api.ts
|
||||
// Regenerate/check: cargo run -q -p server-api --example generate_workdir_api_types -- --check
|
||||
|
||||
@@ -1,68 +1,84 @@
|
||||
// Generated from server-api. Do not edit by hand.
|
||||
// Regenerate: cargo run -q -p server-api --features typescript --example generate_worker_launch_api_types > web/workspace/src/lib/generated/worker-launch-api.ts
|
||||
// @generated by yoi-worker-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:550383b600fe2a2e55630849c7de7a6a24463ad41d0c18dc5d254a3d14328f07)
|
||||
// Options: worker-operation-schema-closure,openapi-3.1,strict-integer-ranges,sorted-output
|
||||
// Output: web/workspace/src/lib/generated/worker-launch-api.ts
|
||||
// Regenerate/check: cargo run -q -p server-api --example generate_worker_launch_api_types -- --check
|
||||
|
||||
import type { Segment } from "./protocol";
|
||||
export type BrowserCreateWorkerResponse = { console_href: string; diagnostics: Array<Diagnostic>; runtime_id: string; worker: WorkerLaunchWorkerSummary; worker_id: string; workspace_id: string; };
|
||||
|
||||
export type BrowserWorkerWorkingDirectorySelection = { alias: string; relative_cwd?: string | null; working_directory_id: string; };
|
||||
|
||||
export type BrowserWorkspaceOrchestratorResponse = { diagnostics: Array<Diagnostic>; disposition: string; online: boolean; worker?: WorkerLaunchWorkerSummary | null; workspace_id: string; };
|
||||
|
||||
export type CreateWorkspaceWorkerRequest = { control_operation_id?: string | null; display_name: string; initial_submit?: Array<Segment>; profile?: string | null; runtime_id: string; ticket_assignment?: CreateWorkspaceWorkerTicketAssignmentRequest | null; workdir_attachments?: Array<BrowserWorkerWorkingDirectorySelection>; };
|
||||
|
||||
export type CreateWorkspaceWorkerTicketAssignmentRequest = { operation_id: string; ticket_id: string; };
|
||||
|
||||
export type Diagnostic = { code: string; message: string; severity: DiagnosticSeverity; };
|
||||
|
||||
export type DiagnosticSeverity = "info" | "warning" | "error";
|
||||
|
||||
export type Diagnostic = { code: string, severity: DiagnosticSeverity, message: string, };
|
||||
export type PasteArtifactAvailability = "available" | "unavailable" | "integrity_failed";
|
||||
|
||||
export type PasteArtifactMediaType = "text_plain_utf8";
|
||||
|
||||
export type PasteArtifactRef = { artifact_id: string; availability: PasteArtifactAvailability; byte_len: number; char_count: number; created_at_ms: number; line_count: number; media_type: PasteArtifactMediaType; sha256: string; source_entry_id: string; };
|
||||
|
||||
export type RepositoryApiError = { diagnostics?: Array<Diagnostic>; error: string; message: string; };
|
||||
|
||||
export type RuntimeWorkerWorkdirAttachmentSummary = { alias: string; working_directory: RuntimeWorkingDirectorySummary; };
|
||||
|
||||
export type RuntimeWorkingDirectoryCleanupTarget = { kind: string; repository_id: string; working_directory_id: string; };
|
||||
|
||||
export type RuntimeWorkingDirectorySummary = { cleanliness?: string | null; cleanup_target?: RuntimeWorkingDirectoryCleanupTarget | null; creation_ref?: string | null; creation_selector?: string | null; creation_tree?: string | null; current_ref?: string | null; current_selector?: string | null; current_tree?: string | null; display_name?: string | null; materializer_kind: WorkingDirectoryMaterializerKind; observed_at_epoch_seconds?: number | null; occupied_by?: WorkingDirectoryOccupancy | null; repository_id: string; status: WorkingDirectoryStatusKind; working_directory_id: string; };
|
||||
|
||||
export type Segment = { content: string; kind: "text"; } | { chars: number; content: string; id: number; kind: "paste"; lines: number; } | { artifact: PasteArtifactRef; kind: "paste_artifact"; } | { file: UploadedFileRef; kind: "uploaded_file"; } | { kind: "file_ref"; path: string; } | { kind: "flow"; selector: string; } | { kind: "unknown"; };
|
||||
|
||||
export type UploadedFileAvailability = "available" | "unavailable" | "integrity_failed";
|
||||
|
||||
export type UploadedFileRef = { artifact_id: string; availability: UploadedFileAvailability; byte_len: number; created_at_ms: number; file_name: string; media_type: string; sha256: string; source_entry_id?: string | null; };
|
||||
|
||||
export type WorkerBusyState = { kind: "run"; state: WorkerRunState; } | { kind: "maintenance"; state: WorkerMaintenanceState; };
|
||||
|
||||
export type WorkerCapabilitySummary = { can_spawn_followup: boolean; can_stop: boolean; };
|
||||
|
||||
export type WorkerImplementationSummary = { display_hint: string; kind: string; };
|
||||
|
||||
export type WorkerLaunchOptionsResponse = { default_profile?: string | null; diagnostics: Array<Diagnostic>; profiles: Array<WorkerLaunchProfileCandidate>; repositories: Array<WorkingDirectoryRepositoryOption>; runtimes: Array<WorkerLaunchRuntimeOption>; working_directories: Array<WorkingDirectorySummary>; workspace_id: string; };
|
||||
|
||||
export type WorkerLaunchProfileCandidate = { description: string; id: string; label: string; };
|
||||
|
||||
export type WorkerLaunchRuntimeOption = { built_in: boolean; diagnostics: Array<Diagnostic>; display_name: string; runtime_id: string; status: string; worker_creation_available: boolean; working_directory_required: boolean; };
|
||||
|
||||
export type WorkerLaunchWorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned: boolean; profile?: string | null; retention_state: string; runtime_id: string; singleton_key?: string | null; state: string; tags: Array<string>; workdir_attachments?: Array<RuntimeWorkerWorkdirAttachmentSummary>; worker_id: string; workspace: WorkerWorkspaceSummary; };
|
||||
|
||||
export type WorkerListResponse = { diagnostics?: Array<Diagnostic>; items: Array<WorkerSummary>; limit: number; source: string; workspace_id: string; };
|
||||
|
||||
export type WorkerMaintenanceState = "compacting";
|
||||
|
||||
export type WorkerRunState = "running" | "pausing" | "paused" | "cancelling";
|
||||
|
||||
export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyState; };
|
||||
|
||||
export type WorkerStateSnapshot = { last_command_id: number; state: WorkerState; };
|
||||
|
||||
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: WorkerStateSnapshot | null; workspace: WorkerWorkspaceSummary; };
|
||||
|
||||
export type WorkerWorkdirAttachmentSummary = { alias: string; working_directory: WorkingDirectorySummary; };
|
||||
|
||||
export type WorkerWorkspaceSummary = { identity: string; visibility: string; workspace_id?: string | null; };
|
||||
|
||||
export type WorkingDirectoryCleanupTarget = { kind: string; repository_key: string; working_directory_id: string; };
|
||||
|
||||
export type WorkingDirectoryMaterializerKind = "runtime_git_clone" | "client_hosted_external";
|
||||
|
||||
export type WorkingDirectoryOccupancy = { display_name: string; linked_at: string; runtime_id: string; worker_id: string; };
|
||||
|
||||
export type WorkingDirectoryRepositoryOption = { default_selector?: string | null; repository_key: string; };
|
||||
|
||||
export type WorkingDirectorySource = { kind: "repository"; repository_key: string; } | { grant_id: string; kind: "external_grant"; };
|
||||
|
||||
export type WorkingDirectoryStatusKind = "active" | "cleanup_pending" | "corrupted" | "not_found" | "unknown";
|
||||
|
||||
export type WorkingDirectoryCleanupTarget = { kind: string, working_directory_id: string, repository_key: string, };
|
||||
|
||||
export type RuntimeWorkingDirectoryCleanupTarget = { kind: string, working_directory_id: string, repository_id: string, };
|
||||
|
||||
export type RuntimeWorkingDirectorySummary = { working_directory_id: string,
|
||||
/**
|
||||
* Optional human-facing label, never a routing key.
|
||||
*/
|
||||
display_name?: string | null, repository_id: string, creation_selector?: string | null, creation_ref?: string | null, creation_tree?: string | null, current_selector?: string | null, current_ref?: string | null, current_tree?: string | null, observed_at_epoch_seconds?: number | null, materializer_kind: WorkingDirectoryMaterializerKind, cleanup_target?: RuntimeWorkingDirectoryCleanupTarget | null, status: WorkingDirectoryStatusKind, cleanliness?: string | null, occupied_by?: WorkingDirectoryOccupancy | null, };
|
||||
|
||||
export type WorkingDirectoryOccupancy = { runtime_id: string, worker_id: string, display_name: string, linked_at: string, };
|
||||
|
||||
export type WorkingDirectorySource = { "kind": "repository", repository_key: string, } | { "kind": "external_grant", grant_id: string, };
|
||||
|
||||
export type WorkingDirectorySummary = { working_directory_id: string,
|
||||
/**
|
||||
* Optional human-facing label, never a routing key.
|
||||
*/
|
||||
display_name?: string | null, source: WorkingDirectorySource, creation_selector?: string | null, creation_ref?: string | null, creation_tree?: string | null, current_selector?: string | null, current_ref?: string | null, current_tree?: string | null, observed_at_epoch_seconds?: number | null, materializer_kind: WorkingDirectoryMaterializerKind, cleanup_target?: WorkingDirectoryCleanupTarget | null, status: WorkingDirectoryStatusKind, cleanliness?: string | null, occupied_by?: WorkingDirectoryOccupancy | null, };
|
||||
|
||||
export type WorkerWorkspaceSummary = { visibility: string, identity: string, workspace_id?: string | null, };
|
||||
|
||||
export type WorkerImplementationSummary = { kind: string, display_hint: string, };
|
||||
|
||||
export type WorkerCapabilitySummary = { can_stop: boolean, can_spawn_followup: boolean, };
|
||||
|
||||
export type RuntimeWorkerWorkdirAttachmentSummary = { alias: string, working_directory: RuntimeWorkingDirectorySummary, };
|
||||
|
||||
export type WorkerLaunchWorkerSummary = { runtime_id: string, worker_id: string, host_id: string, display_name: string, label: string, profile: string | null, singleton_key: string | null, tags: Array<string>, workspace: WorkerWorkspaceSummary, state: string, last_seen_at: string | null, pinned: boolean, retention_state: string, implementation: WorkerImplementationSummary, capabilities: WorkerCapabilitySummary, workdir_attachments?: Array<RuntimeWorkerWorkdirAttachmentSummary>, diagnostics: Array<Diagnostic>, };
|
||||
|
||||
export type WorkerLaunchRuntimeOption = { runtime_id: string, display_name: string, built_in: boolean, worker_creation_available: boolean, working_directory_required: boolean, status: string, diagnostics: Array<Diagnostic>, };
|
||||
|
||||
export type WorkerLaunchProfileCandidate = { id: string, label: string, description: string, };
|
||||
|
||||
export type WorkingDirectoryRepositoryOption = { repository_key: string, default_selector?: string | null, };
|
||||
|
||||
export type WorkerLaunchOptionsResponse = { workspace_id: string, runtimes: Array<WorkerLaunchRuntimeOption>, default_profile: string | null, profiles: Array<WorkerLaunchProfileCandidate>, repositories: Array<WorkingDirectoryRepositoryOption>, working_directories: Array<WorkingDirectorySummary>, diagnostics: Array<Diagnostic>, };
|
||||
|
||||
export type BrowserWorkerWorkingDirectorySelection = {
|
||||
/**
|
||||
* Stable Worker-local routing alias.
|
||||
*/
|
||||
alias: string, working_directory_id: string, relative_cwd: string | null, };
|
||||
|
||||
export type CreateWorkspaceWorkerTicketAssignmentRequest = { ticket_id: string, operation_id: string, };
|
||||
|
||||
export type CreateWorkspaceWorkerRequest = { runtime_id: string, display_name: string, profile: string | null, ticket_assignment: CreateWorkspaceWorkerTicketAssignmentRequest | null, initial_submit: Array<Segment>, workdir_attachments: Array<BrowserWorkerWorkingDirectorySelection>,
|
||||
/**
|
||||
* Backend idempotency key used only for authenticated Worker-owned spawn/control.
|
||||
*/
|
||||
control_operation_id: string | null, };
|
||||
|
||||
export type BrowserCreateWorkerResponse = { workspace_id: string, runtime_id: string, worker_id: string, console_href: string, worker: WorkerLaunchWorkerSummary, diagnostics: Array<Diagnostic>, };
|
||||
|
||||
export type BrowserWorkspaceOrchestratorResponse = { workspace_id: string, online: boolean, disposition: string, worker?: WorkerLaunchWorkerSummary | null, diagnostics: Array<Diagnostic>, };
|
||||
export type WorkingDirectorySummary = { cleanliness?: string | null; cleanup_target?: WorkingDirectoryCleanupTarget | null; creation_ref?: string | null; creation_selector?: string | null; creation_tree?: string | null; current_ref?: string | null; current_selector?: string | null; current_tree?: string | null; display_name?: string | null; materializer_kind: WorkingDirectoryMaterializerKind; observed_at_epoch_seconds?: number | null; occupied_by?: WorkingDirectoryOccupancy | null; source: WorkingDirectorySource; status: WorkingDirectoryStatusKind; working_directory_id: string; };
|
||||
|
||||
@@ -6,15 +6,20 @@ import type {
|
||||
CreateWorkspaceWorkerTicketAssignmentRequest,
|
||||
Diagnostic,
|
||||
DiagnosticSeverity,
|
||||
RepositoryApiError,
|
||||
RuntimeWorkerWorkdirAttachmentSummary,
|
||||
RuntimeWorkingDirectoryCleanupTarget,
|
||||
RuntimeWorkingDirectorySummary,
|
||||
RuntimeWorkerWorkdirAttachmentSummary,
|
||||
WorkerCapabilitySummary,
|
||||
WorkerImplementationSummary,
|
||||
WorkerLaunchOptionsResponse,
|
||||
WorkerLaunchProfileCandidate,
|
||||
WorkerLaunchRuntimeOption,
|
||||
WorkerLaunchWorkerSummary,
|
||||
WorkerListResponse,
|
||||
WorkerStateSnapshot,
|
||||
WorkerSummary,
|
||||
WorkerWorkdirAttachmentSummary,
|
||||
WorkerWorkspaceSummary,
|
||||
WorkingDirectoryRepositoryOption,
|
||||
} from "$lib/generated/worker-launch-api";
|
||||
@@ -45,8 +50,14 @@ function exact(
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_STRING_LENGTH = 65_536;
|
||||
const MAX_COLLECTION_LENGTH = 4_096;
|
||||
|
||||
function string(value: unknown, label: string): string {
|
||||
if (typeof value !== "string") throw new Error(`${label} must be a string`);
|
||||
if (value.length > MAX_STRING_LENGTH) {
|
||||
throw new Error(`${label} exceeds its length limit`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -56,8 +67,8 @@ function boolean(value: unknown, label: string): boolean {
|
||||
}
|
||||
|
||||
function number(value: unknown, label: string): number {
|
||||
if (typeof value !== "number" || !Number.isFinite(value)) {
|
||||
throw new Error(`${label} must be a finite number`);
|
||||
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
||||
throw new Error(`${label} must be a safe integer`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -72,6 +83,9 @@ function array<T>(
|
||||
parse: (item: unknown, label: string) => T,
|
||||
): T[] {
|
||||
if (!Array.isArray(value)) throw new Error(`${label} must be an array`);
|
||||
if (value.length > MAX_COLLECTION_LENGTH) {
|
||||
throw new Error(`${label} exceeds its item limit`);
|
||||
}
|
||||
return value.map((item, index) => parse(item, `${label}[${index}]`));
|
||||
}
|
||||
|
||||
@@ -165,6 +179,18 @@ function repositoryOption(
|
||||
};
|
||||
}
|
||||
|
||||
export function parseWorkerApiError(value: unknown): RepositoryApiError {
|
||||
const item = record(value, "Worker API error");
|
||||
exact(item, ["error", "message", "diagnostics"], "Worker API error");
|
||||
return {
|
||||
error: string(item.error, "error"),
|
||||
message: string(item.message, "message"),
|
||||
diagnostics: item.diagnostics === undefined
|
||||
? []
|
||||
: array(item.diagnostics, "diagnostics", diagnostic),
|
||||
};
|
||||
}
|
||||
|
||||
export function parseWorkerLaunchOptionsResponse(
|
||||
value: unknown,
|
||||
): WorkerLaunchOptionsResponse {
|
||||
@@ -237,6 +263,181 @@ function capabilitySummary(
|
||||
};
|
||||
}
|
||||
|
||||
function workerStateSnapshot(
|
||||
value: unknown,
|
||||
label: string,
|
||||
): WorkerStateSnapshot {
|
||||
const snapshot = record(value, label);
|
||||
exact(snapshot, ["last_command_id", "state"], label);
|
||||
const state = record(snapshot.state, `${label}.state`);
|
||||
const kind = string(state.kind, `${label}.state.kind`);
|
||||
if (kind === "idle") {
|
||||
exact(state, ["kind"], `${label}.state`);
|
||||
return {
|
||||
last_command_id: unsignedInteger(
|
||||
snapshot.last_command_id,
|
||||
`${label}.last_command_id`,
|
||||
),
|
||||
state: { kind: "idle" },
|
||||
};
|
||||
}
|
||||
if (kind !== "busy") throw new Error(`${label}.state.kind is invalid`);
|
||||
exact(state, ["kind", "state"], `${label}.state`);
|
||||
const busy = record(state.state, `${label}.state.state`);
|
||||
exact(busy, ["kind", "state"], `${label}.state.state`);
|
||||
const busyKind = string(busy.kind, `${label}.state.state.kind`);
|
||||
const busyState = string(busy.state, `${label}.state.state.state`);
|
||||
if (
|
||||
(busyKind === "run" &&
|
||||
["running", "pausing", "paused", "cancelling"].includes(busyState)) ||
|
||||
(busyKind === "maintenance" && busyState === "compacting")
|
||||
) {
|
||||
return {
|
||||
last_command_id: unsignedInteger(
|
||||
snapshot.last_command_id,
|
||||
`${label}.last_command_id`,
|
||||
),
|
||||
state: {
|
||||
kind: "busy",
|
||||
state: busyKind === "run"
|
||||
? {
|
||||
kind: "run",
|
||||
state: busyState as "running" | "pausing" | "paused" | "cancelling",
|
||||
}
|
||||
: { kind: "maintenance", state: "compacting" },
|
||||
},
|
||||
};
|
||||
}
|
||||
throw new Error(`${label}.state.state is invalid`);
|
||||
}
|
||||
|
||||
function workerWorkdirAttachment(
|
||||
value: unknown,
|
||||
label: string,
|
||||
): WorkerWorkdirAttachmentSummary {
|
||||
const item = record(value, label);
|
||||
exact(item, ["alias", "working_directory"], label);
|
||||
return {
|
||||
alias: string(item.alias, `${label}.alias`),
|
||||
working_directory: parseWorkingDirectorySummary(item.working_directory),
|
||||
};
|
||||
}
|
||||
|
||||
export type ParsedWorkerSummary =
|
||||
& Omit<
|
||||
WorkerSummary,
|
||||
"display_name" | "tags" | "diagnostics"
|
||||
>
|
||||
& {
|
||||
display_name: string;
|
||||
tags: string[];
|
||||
diagnostics: Diagnostic[];
|
||||
};
|
||||
|
||||
export type ParsedWorkerListResponse = Omit<WorkerListResponse, "items"> & {
|
||||
items: ParsedWorkerSummary[];
|
||||
};
|
||||
|
||||
export function parseWorkerSummary(
|
||||
value: unknown,
|
||||
label = "Worker summary",
|
||||
): ParsedWorkerSummary {
|
||||
const item = record(value, label);
|
||||
exact(
|
||||
item,
|
||||
[
|
||||
"runtime_id",
|
||||
"worker_id",
|
||||
"resource_key",
|
||||
"host_id",
|
||||
"display_name",
|
||||
"label",
|
||||
"profile",
|
||||
"singleton_key",
|
||||
"tags",
|
||||
"workspace",
|
||||
"state",
|
||||
"worker_state",
|
||||
"last_seen_at",
|
||||
"pinned",
|
||||
"retention_state",
|
||||
"implementation",
|
||||
"capabilities",
|
||||
"workdir_attachments",
|
||||
"diagnostics",
|
||||
],
|
||||
label,
|
||||
);
|
||||
return {
|
||||
runtime_id: string(item.runtime_id, `${label}.runtime_id`),
|
||||
worker_id: string(item.worker_id, `${label}.worker_id`),
|
||||
resource_key: string(item.resource_key, `${label}.resource_key`),
|
||||
host_id: string(item.host_id, `${label}.host_id`),
|
||||
display_name: item.display_name === undefined
|
||||
? ""
|
||||
: string(item.display_name, `${label}.display_name`),
|
||||
label: string(item.label, `${label}.label`),
|
||||
profile: optional(item.profile, `${label}.profile`, string),
|
||||
singleton_key: optional(
|
||||
item.singleton_key,
|
||||
`${label}.singleton_key`,
|
||||
string,
|
||||
),
|
||||
tags: item.tags === undefined
|
||||
? []
|
||||
: array(item.tags, `${label}.tags`, string),
|
||||
workspace: workspaceSummary(item.workspace, `${label}.workspace`),
|
||||
state: string(item.state, `${label}.state`),
|
||||
worker_state: optional(
|
||||
item.worker_state,
|
||||
`${label}.worker_state`,
|
||||
workerStateSnapshot,
|
||||
),
|
||||
last_seen_at: optional(item.last_seen_at, `${label}.last_seen_at`, string),
|
||||
pinned: item.pinned === undefined
|
||||
? false
|
||||
: boolean(item.pinned, `${label}.pinned`),
|
||||
retention_state: item.retention_state === undefined
|
||||
? ""
|
||||
: string(item.retention_state, `${label}.retention_state`),
|
||||
implementation: implementationSummary(
|
||||
item.implementation,
|
||||
`${label}.implementation`,
|
||||
),
|
||||
capabilities: capabilitySummary(item.capabilities, `${label}.capabilities`),
|
||||
workdir_attachments: item.workdir_attachments === undefined
|
||||
? undefined
|
||||
: array(
|
||||
item.workdir_attachments,
|
||||
`${label}.workdir_attachments`,
|
||||
workerWorkdirAttachment,
|
||||
),
|
||||
diagnostics: item.diagnostics === undefined
|
||||
? []
|
||||
: array(item.diagnostics, `${label}.diagnostics`, diagnostic),
|
||||
};
|
||||
}
|
||||
|
||||
export function parseWorkerListResponse(
|
||||
value: unknown,
|
||||
): ParsedWorkerListResponse {
|
||||
const item = record(value, "Worker list response");
|
||||
exact(
|
||||
item,
|
||||
["workspace_id", "limit", "items", "source", "diagnostics"],
|
||||
"Worker list response",
|
||||
);
|
||||
return {
|
||||
workspace_id: string(item.workspace_id, "workspace_id"),
|
||||
limit: unsignedInteger(item.limit, "limit"),
|
||||
items: array(item.items, "items", parseWorkerSummary),
|
||||
source: string(item.source, "source"),
|
||||
diagnostics: item.diagnostics === undefined
|
||||
? []
|
||||
: array(item.diagnostics, "diagnostics", diagnostic),
|
||||
};
|
||||
}
|
||||
|
||||
function runtimeCleanupTarget(
|
||||
value: unknown,
|
||||
label: string,
|
||||
|
||||
@@ -9,10 +9,14 @@ import type {
|
||||
BrowserCreateWorkerResponse as SharedBrowserCreateWorkerResponse,
|
||||
BrowserWorkerWorkingDirectorySelection
|
||||
as SharedBrowserWorkerWorkingDirectorySelection,
|
||||
Diagnostic as SharedDiagnostic,
|
||||
WorkerCapabilitySummary as SharedWorkerCapabilitySummary,
|
||||
WorkerLaunchOptionsResponse as SharedWorkerLaunchOptionsResponse,
|
||||
WorkerLaunchProfileCandidate as SharedWorkerLaunchProfileCandidate,
|
||||
WorkerLaunchRuntimeOption as SharedWorkerLaunchRuntimeOption,
|
||||
WorkerLaunchWorkerSummary as WorkerSummary,
|
||||
WorkerLaunchWorkerSummary,
|
||||
WorkerSummary as SharedWorkerSummary,
|
||||
WorkerWorkdirAttachmentSummary as SharedWorkerWorkdirAttachmentSummary,
|
||||
WorkingDirectoryRepositoryOption as SharedWorkingDirectoryRepositoryOption,
|
||||
} from "$lib/generated/worker-launch-api";
|
||||
import type {
|
||||
@@ -53,11 +57,7 @@ export type {
|
||||
};
|
||||
export type WorkspaceResponse = SharedWorkspaceResponse;
|
||||
|
||||
export type Diagnostic = {
|
||||
code: string;
|
||||
severity: string;
|
||||
message: string;
|
||||
};
|
||||
export type Diagnostic = SharedDiagnostic;
|
||||
|
||||
export type Runtime = {
|
||||
runtime_id: string;
|
||||
@@ -78,35 +78,17 @@ export type Runtime = {
|
||||
};
|
||||
};
|
||||
|
||||
export type WorkerCapabilities = {
|
||||
can_stop: boolean;
|
||||
can_spawn_followup: boolean;
|
||||
};
|
||||
export type WorkerCapabilities = SharedWorkerCapabilitySummary;
|
||||
|
||||
export type WorkerWorkdirAttachment = {
|
||||
alias: string;
|
||||
working_directory: WorkingDirectorySummary;
|
||||
};
|
||||
export type WorkerWorkdirAttachment = SharedWorkerWorkdirAttachmentSummary;
|
||||
|
||||
export type Worker = {
|
||||
runtime_id: string;
|
||||
worker_id: string;
|
||||
resource_key: string;
|
||||
host_id: string;
|
||||
export type Worker = Omit<
|
||||
SharedWorkerSummary,
|
||||
"display_name" | "tags" | "worker_state" | "diagnostics"
|
||||
> & {
|
||||
display_name: string;
|
||||
label: string;
|
||||
profile?: string | null;
|
||||
singleton_key?: string | null;
|
||||
tags: string[];
|
||||
workspace: { visibility: string; identity: string };
|
||||
state: string;
|
||||
worker_state?: WorkerStateSnapshot | null;
|
||||
pinned?: boolean;
|
||||
retention_state?: string;
|
||||
last_seen_at?: string | null;
|
||||
implementation: { kind: string; display_hint: string };
|
||||
capabilities: WorkerCapabilities;
|
||||
workdir_attachments?: WorkerWorkdirAttachment[];
|
||||
diagnostics: Diagnostic[];
|
||||
};
|
||||
|
||||
@@ -121,7 +103,7 @@ export type WorkerRestoreState =
|
||||
|
||||
export type WorkerRestoreResult = {
|
||||
state: WorkerRestoreState;
|
||||
worker?: WorkerSummary | null;
|
||||
worker?: WorkerLaunchWorkerSummary | null;
|
||||
diagnostics: Diagnostic[];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { loadJson, workspaceApiPath } from "$lib/workspace/api/http";
|
||||
import { parseWorkerListResponse } from "$lib/workspace/api/workers";
|
||||
import { parseRuntimeCleanupPlan } from "$lib/workspace/api/runtime-workers";
|
||||
import type {
|
||||
ListResponse,
|
||||
RuntimeCleanupPlanResponse,
|
||||
Worker,
|
||||
} from "$lib/workspace/sidebar/types";
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export const load: PageLoad = async ({ fetch, params }) => {
|
||||
const workers = await loadJson<ListResponse<Worker>>(
|
||||
const workers = await loadJson(
|
||||
fetch,
|
||||
workspaceApiPath(params.workspaceId, "/workers"),
|
||||
undefined,
|
||||
parseWorkerListResponse,
|
||||
{ diagnosticLabel: "Worker API", maxResponseBytes: 8 * 1024 * 1024 },
|
||||
);
|
||||
const runtimeIds = Array.from(
|
||||
new Set(workers.data?.items.map((worker) => worker.runtime_id) ?? []),
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
import { loadJson, workspaceApiPath } from "$lib/workspace/api/http";
|
||||
import { parseWorkerSummary } from "$lib/workspace/api/workers";
|
||||
import {
|
||||
canonicalResourceReference,
|
||||
resourceKey,
|
||||
} from "$lib/workspace/resource-links";
|
||||
import type { Worker } from "$lib/workspace/sidebar/types";
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export const load = (async ({ fetch, params }) => {
|
||||
const reference = resourceKey(params.workerRef);
|
||||
const result = await loadJson<Worker>(
|
||||
const result = await loadJson(
|
||||
fetch,
|
||||
workspaceApiPath(
|
||||
params.workspaceId,
|
||||
`/workers/${encodeURIComponent(reference)}`,
|
||||
),
|
||||
undefined,
|
||||
parseWorkerSummary,
|
||||
{ diagnosticLabel: "Worker API", maxResponseBytes: 8 * 1024 * 1024 },
|
||||
);
|
||||
if (result.data?.resource_key) {
|
||||
const canonical = canonicalResourceReference(
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
import { loadJson, workspaceApiPath } from "$lib/workspace/api/http";
|
||||
import { parseWorkerSummary } from "$lib/workspace/api/workers";
|
||||
import {
|
||||
canonicalResourceReference,
|
||||
resourceKey,
|
||||
} from "$lib/workspace/resource-links";
|
||||
import type { Worker } from "$lib/workspace/sidebar/types";
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
export const load = (async ({ fetch, params }) => {
|
||||
const reference = resourceKey(params.workerRef);
|
||||
const result = await loadJson<Worker>(
|
||||
const result = await loadJson(
|
||||
fetch,
|
||||
workspaceApiPath(
|
||||
params.workspaceId,
|
||||
`/workers/${encodeURIComponent(reference)}`,
|
||||
),
|
||||
undefined,
|
||||
parseWorkerSummary,
|
||||
{ diagnosticLabel: "Worker API", maxResponseBytes: 8 * 1024 * 1024 },
|
||||
);
|
||||
if (result.data?.resource_key) {
|
||||
const canonical = canonicalResourceReference(
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { untrack } from 'svelte';
|
||||
import { workspaceApiPath } from '$lib/workspace/api/http';
|
||||
import { readBoundedJson, workspaceApiPath } from '$lib/workspace/api/http';
|
||||
import {
|
||||
parseWorkingDirectoryCreateResponse,
|
||||
validateWorkingDirectoryCreateRequest,
|
||||
} from '$lib/workspace/api/workdirs';
|
||||
import {
|
||||
parseBrowserCreateWorkerResponse,
|
||||
parseWorkerApiError,
|
||||
parseWorkerLaunchOptionsResponse,
|
||||
} from '$lib/workspace/api/workers';
|
||||
import { formatCurrentWorkdirRevision } from '$lib/workspace/settings/workdir-revision';
|
||||
@@ -29,12 +30,6 @@
|
||||
diagnostics: Diagnostic[];
|
||||
};
|
||||
|
||||
type ErrorPayload = {
|
||||
error?: { message?: string; code?: string } | string;
|
||||
message?: string;
|
||||
diagnostics?: Diagnostic[];
|
||||
};
|
||||
|
||||
function workdirOptionLabel(directory: WorkingDirectorySummary): string {
|
||||
const repositoryKey = directory.source.kind === 'repository'
|
||||
? directory.source.repository_key
|
||||
@@ -171,7 +166,9 @@
|
||||
if (!response.ok) {
|
||||
throw new Error(`worker launch options failed (${response.status})`);
|
||||
}
|
||||
const payload = parseWorkerLaunchOptionsResponse(await response.json());
|
||||
const payload = parseWorkerLaunchOptionsResponse(
|
||||
await readBoundedJson(response, 8 * 1024 * 1024),
|
||||
);
|
||||
options = payload;
|
||||
const form = defaultWorkerLaunchForm(payload, {
|
||||
runtime_id: runtimeId,
|
||||
@@ -313,7 +310,9 @@
|
||||
submitError = await responseDisplayError(response, 'worker create failed');
|
||||
return;
|
||||
}
|
||||
const payload = parseBrowserCreateWorkerResponse(await response.json());
|
||||
const payload = parseBrowserCreateWorkerResponse(
|
||||
await readBoundedJson(response, 8 * 1024 * 1024),
|
||||
);
|
||||
await goto(payload.console_href);
|
||||
} catch (err) {
|
||||
submitError = exceptionDisplayError(err, 'worker create failed');
|
||||
@@ -324,18 +323,13 @@
|
||||
|
||||
async function responseDisplayError(response: Response, fallback: string): Promise<DisplayError> {
|
||||
try {
|
||||
const payload = (await response.json()) as ErrorPayload;
|
||||
const diagnostics = Array.isArray(payload.diagnostics) ? payload.diagnostics : [];
|
||||
if (typeof payload.error === 'object' && payload.error?.message) {
|
||||
return {
|
||||
message: `${payload.error.code ?? 'request_failed'}: ${payload.error.message}`,
|
||||
diagnostics,
|
||||
};
|
||||
}
|
||||
if (payload.message) {
|
||||
const code = typeof payload.error === 'string' ? payload.error : 'request_failed';
|
||||
return { message: `${code}: ${payload.message}`, diagnostics };
|
||||
}
|
||||
const payload = parseWorkerApiError(
|
||||
await readBoundedJson(response, 1024 * 1024),
|
||||
);
|
||||
return {
|
||||
message: `${payload.error}: ${payload.message}`,
|
||||
diagnostics: payload.diagnostics ?? [],
|
||||
};
|
||||
} catch {
|
||||
// fall through
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user