Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
98 lines
3.3 KiB
TypeScript
98 lines
3.3 KiB
TypeScript
import { computerSupportsUpdate } from "@rakazo/adapters";
|
|
import type { ComputerStatus } from "@rakazo/contracts";
|
|
import { ACTIVE_RUN_STATUSES, computerScreenSize } from "@rakazo/core";
|
|
import type { PrismaClient } from "@rakazo/db";
|
|
|
|
/** Mirrors computer.takeover: an execution lease blocks user control unless a takeover is pending. */
|
|
export function executionBlocksUserTakeover(input: {
|
|
hasLease: boolean;
|
|
leaseExpiresAt: Date | null | undefined;
|
|
runStatus: string | null | undefined;
|
|
now?: number;
|
|
takeoverRequested?: boolean;
|
|
}): boolean {
|
|
if (!input.hasLease) return false;
|
|
if (input.runStatus === "waiting_takeover" || input.takeoverRequested) return false;
|
|
const now = input.now ?? Date.now();
|
|
const leaseActive = Boolean(input.leaseExpiresAt && input.leaseExpiresAt.getTime() > now);
|
|
const runActive = Boolean(
|
|
input.runStatus && (ACTIVE_RUN_STATUSES as readonly string[]).includes(input.runStatus),
|
|
);
|
|
return leaseActive || runActive;
|
|
}
|
|
|
|
export async function resolveBusyBotName(
|
|
prisma: PrismaClient,
|
|
input: {
|
|
computerId: string | null | undefined;
|
|
botId: string;
|
|
botName: string;
|
|
},
|
|
): Promise<string | null> {
|
|
if (!input.computerId) return null;
|
|
const lease = await prisma.computerExecutionLease.findUnique({
|
|
where: { computerId_botId: { computerId: input.computerId, botId: input.botId } },
|
|
select: { expiresAt: true, runId: true, computer: { select: { controlRunId: true } } },
|
|
});
|
|
if (!lease) return null;
|
|
const run = await prisma.run.findUnique({
|
|
where: { id: lease.runId },
|
|
select: { status: true },
|
|
});
|
|
return executionBlocksUserTakeover({
|
|
hasLease: true,
|
|
leaseExpiresAt: lease.expiresAt,
|
|
runStatus: run?.status,
|
|
takeoverRequested: lease.computer.controlRunId === lease.runId,
|
|
})
|
|
? input.botName
|
|
: null;
|
|
}
|
|
|
|
export function toComputerStatus(
|
|
botId: string,
|
|
computer: {
|
|
kind: string;
|
|
state: string;
|
|
scope: string;
|
|
controlHolder: string;
|
|
controlBotId?: string | null;
|
|
controlRunId?: string | null;
|
|
homeRevision: string;
|
|
maintenanceId?: string | null;
|
|
} | null,
|
|
busyBotName: string | null = null,
|
|
): ComputerStatus {
|
|
const state = computer?.maintenanceId
|
|
? "booting"
|
|
: computer?.state === "suspending"
|
|
? "running"
|
|
: computer?.state === "stopped" ||
|
|
computer?.state === "booting" ||
|
|
computer?.state === "running" ||
|
|
computer?.state === "suspended" ||
|
|
computer?.state === "error"
|
|
? computer.state
|
|
: "stopped";
|
|
const screen = computerScreenSize(computer?.kind);
|
|
const validKinds = new Set(["docker", "e2b", "daytona", "box", "desktop", "fake", "none"]);
|
|
const kind = (
|
|
computer?.kind && validKinds.has(computer.kind) ? computer.kind : "none"
|
|
) as ComputerStatus["kind"];
|
|
return {
|
|
botId,
|
|
mode: computer?.scope === "dedicated" ? "dedicated" : "team",
|
|
kind,
|
|
state,
|
|
controlHolder: (computer?.controlHolder ?? "none") as ComputerStatus["controlHolder"],
|
|
controlBotId: computer?.controlBotId ?? null,
|
|
takeoverRequested: Boolean(computer?.controlRunId),
|
|
screenAvailable: !computer?.maintenanceId && (state === "running" || state === "booting"),
|
|
screenWidth: screen.width,
|
|
screenHeight: screen.height,
|
|
homeRevision: computer?.homeRevision ?? null,
|
|
busyBotName,
|
|
canUpdate: computerSupportsUpdate(kind),
|
|
};
|
|
}
|