fix: separate worker observation freshness
This commit is contained in:
@@ -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:80be292e32441730f7de890e64836f4ca9655576d655e60e6d44daf5227a1b1c)
|
||||
// Input contract: 0.1.0 (sha256:a92b7346166ec2316878ef38b0426090cb4bdd0d5b96cae3014bef35c60df02a)
|
||||
// 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,6 +55,8 @@ 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 SubscriptionWorkerAvailability = "observed" | "unavailable";
|
||||
|
||||
export type WorkerBusyState = { kind: "run"; state: WorkerRunState; } | { kind: "maintenance"; state: WorkerMaintenanceState; };
|
||||
|
||||
export type WorkerCapabilitySummary = { can_spawn_followup: boolean; can_stop: boolean; };
|
||||
@@ -69,7 +71,7 @@ export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyS
|
||||
|
||||
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 WorkerSummary = { availability: SubscriptionWorkerAvailability; 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:80be292e32441730f7de890e64836f4ca9655576d655e60e6d44daf5227a1b1c)
|
||||
// Input contract: 0.1.0 (sha256:a92b7346166ec2316878ef38b0426090cb4bdd0d5b96cae3014bef35c60df02a)
|
||||
// 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,7 +105,7 @@ 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?: WorkerStateSnapshot | null; workspace: WorkerWorkspaceSummary; };
|
||||
export type RuntimeWorkerShowResponse = { availability: SubscriptionWorkerAvailability; 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; };
|
||||
|
||||
@@ -125,6 +125,8 @@ export type RuntimeWorkerSummary = { capabilities: WorkerCapabilitySummary; diag
|
||||
|
||||
export type RuntimeWorkerTicketAssignmentRequest = { operation_id: string; ticket_id: string; };
|
||||
|
||||
export type SubscriptionWorkerAvailability = "observed" | "unavailable";
|
||||
|
||||
export type UpdateRemoteRuntimeRequest = { display_name?: string | null; endpoint: string; };
|
||||
|
||||
export type UploadedFileAvailability = "available" | "unavailable" | "integrity_failed";
|
||||
@@ -159,7 +161,7 @@ export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyS
|
||||
|
||||
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 WorkerSummary = { availability: SubscriptionWorkerAvailability; 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-worker-openapi-typescript@1. Do not edit.
|
||||
// Input: openapi/server-api.json
|
||||
// Input contract: 0.1.0 (sha256:80be292e32441730f7de890e64836f4ca9655576d655e60e6d44daf5227a1b1c)
|
||||
// Input contract: 0.1.0 (sha256:a92b7346166ec2316878ef38b0426090cb4bdd0d5b96cae3014bef35c60df02a)
|
||||
// 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
|
||||
@@ -35,6 +35,8 @@ export type RuntimeWorkingDirectorySummary = { cleanliness?: string | null; clea
|
||||
|
||||
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 SubscriptionWorkerAvailability = "observed" | "unavailable";
|
||||
|
||||
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; };
|
||||
@@ -63,7 +65,7 @@ export type WorkerState = { kind: "idle"; } | { kind: "busy"; state: WorkerBusyS
|
||||
|
||||
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 WorkerSummary = { availability: SubscriptionWorkerAvailability; 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; };
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
parseBrowserWorkspaceOrchestratorResponse,
|
||||
parseCreateWorkspaceWorkerRequest,
|
||||
parseWorkerLaunchOptionsResponse,
|
||||
parseWorkerSummary,
|
||||
} from "./workers.ts";
|
||||
|
||||
const worker = {
|
||||
@@ -62,6 +63,39 @@ const worker = {
|
||||
diagnostics: [],
|
||||
};
|
||||
|
||||
Deno.test("Worker summary parser enforces observation freshness", () => {
|
||||
const unavailable = {
|
||||
...worker,
|
||||
resource_key: "W-1",
|
||||
availability: "unavailable",
|
||||
state: "unavailable",
|
||||
};
|
||||
const parsed = parseWorkerSummary(unavailable);
|
||||
assertEquals(parsed.availability, "unavailable");
|
||||
assertEquals(parsed.worker_state, undefined);
|
||||
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerSummary({
|
||||
...unavailable,
|
||||
worker_state: {
|
||||
last_command_id: 0,
|
||||
state: { kind: "idle" },
|
||||
},
|
||||
}),
|
||||
Error,
|
||||
"worker_state must be absent",
|
||||
);
|
||||
|
||||
const observedStopped = parseWorkerSummary({
|
||||
...unavailable,
|
||||
availability: "observed",
|
||||
state: "stopped",
|
||||
});
|
||||
assertEquals(observedStopped.availability, "observed");
|
||||
assertEquals(observedStopped.state, "stopped");
|
||||
});
|
||||
|
||||
Deno.test("Worker launch options parser accepts the generated wire shape", () => {
|
||||
const parsed = parseWorkerLaunchOptionsResponse({
|
||||
workspace_id: "workspace-a",
|
||||
|
||||
@@ -343,6 +343,10 @@ export function parseWorkerSummary(
|
||||
label = "Worker summary",
|
||||
): ParsedWorkerSummary {
|
||||
const item = record(value, label);
|
||||
const availability = string(item.availability, `${label}.availability`);
|
||||
if (availability !== "observed" && availability !== "unavailable") {
|
||||
throw new Error(`${label}.availability is invalid`);
|
||||
}
|
||||
exact(
|
||||
item,
|
||||
[
|
||||
@@ -356,6 +360,7 @@ export function parseWorkerSummary(
|
||||
"singleton_key",
|
||||
"tags",
|
||||
"workspace",
|
||||
"availability",
|
||||
"state",
|
||||
"worker_state",
|
||||
"last_seen_at",
|
||||
@@ -368,6 +373,16 @@ export function parseWorkerSummary(
|
||||
],
|
||||
label,
|
||||
);
|
||||
const workerState = optional(
|
||||
item.worker_state,
|
||||
`${label}.worker_state`,
|
||||
workerStateSnapshot,
|
||||
);
|
||||
if (availability === "unavailable" && workerState != null) {
|
||||
throw new Error(
|
||||
`${label}.worker_state must be absent when availability is unavailable`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
runtime_id: string(item.runtime_id, `${label}.runtime_id`),
|
||||
worker_id: string(item.worker_id, `${label}.worker_id`),
|
||||
@@ -387,12 +402,9 @@ export function parseWorkerSummary(
|
||||
? []
|
||||
: array(item.tags, `${label}.tags`, string),
|
||||
workspace: workspaceSummary(item.workspace, `${label}.workspace`),
|
||||
availability,
|
||||
state: string(item.state, `${label}.state`),
|
||||
worker_state: optional(
|
||||
item.worker_state,
|
||||
`${label}.worker_state`,
|
||||
workerStateSnapshot,
|
||||
),
|
||||
worker_state: workerState,
|
||||
last_seen_at: optional(item.last_seen_at, `${label}.last_seen_at`, string),
|
||||
pinned: item.pinned === undefined
|
||||
? false
|
||||
|
||||
@@ -146,6 +146,7 @@ function projectWorker(
|
||||
visibility: "workspace",
|
||||
identity: "runtime_subscription_worker",
|
||||
},
|
||||
availability: worker.availability,
|
||||
state: liveWorkerState(worker),
|
||||
worker_state: worker.worker_state,
|
||||
pinned: false,
|
||||
|
||||
Reference in New Issue
Block a user