Address runtime workspace review feedback
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
b3d61a7561
commit
92ebad3d42
3 changed files with 47 additions and 38 deletions
|
|
@ -62,6 +62,36 @@ export const executionWorkspaceCloseGitReadinessSchema = z.object({
|
||||||
createdByRuntime: z.boolean(),
|
createdByRuntime: z.boolean(),
|
||||||
}).strict();
|
}).strict();
|
||||||
|
|
||||||
|
export const workspaceRuntimeServiceSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
companyId: z.string().uuid(),
|
||||||
|
projectId: z.string().uuid().nullable(),
|
||||||
|
projectWorkspaceId: z.string().uuid().nullable(),
|
||||||
|
executionWorkspaceId: z.string().uuid().nullable(),
|
||||||
|
issueId: z.string().uuid().nullable(),
|
||||||
|
scopeType: z.enum(["project_workspace", "execution_workspace", "run", "agent"]),
|
||||||
|
scopeId: z.string().nullable(),
|
||||||
|
serviceName: z.string(),
|
||||||
|
status: z.enum(["starting", "running", "stopped", "failed"]),
|
||||||
|
lifecycle: z.enum(["shared", "ephemeral"]),
|
||||||
|
reuseKey: z.string().nullable(),
|
||||||
|
command: z.string().nullable(),
|
||||||
|
cwd: z.string().nullable(),
|
||||||
|
port: z.number().int().nullable(),
|
||||||
|
url: z.string().nullable(),
|
||||||
|
provider: z.enum(["local_process", "adapter_managed"]),
|
||||||
|
providerRef: z.string().nullable(),
|
||||||
|
ownerAgentId: z.string().uuid().nullable(),
|
||||||
|
startedByRunId: z.string().uuid().nullable(),
|
||||||
|
lastUsedAt: z.coerce.date(),
|
||||||
|
startedAt: z.coerce.date(),
|
||||||
|
stoppedAt: z.coerce.date().nullable(),
|
||||||
|
stopPolicy: z.record(z.unknown()).nullable(),
|
||||||
|
healthStatus: z.enum(["unknown", "healthy", "unhealthy"]),
|
||||||
|
createdAt: z.coerce.date(),
|
||||||
|
updatedAt: z.coerce.date(),
|
||||||
|
}).strict();
|
||||||
|
|
||||||
export const executionWorkspaceCloseReadinessSchema = z.object({
|
export const executionWorkspaceCloseReadinessSchema = z.object({
|
||||||
workspaceId: z.string().uuid(),
|
workspaceId: z.string().uuid(),
|
||||||
state: executionWorkspaceCloseReadinessStateSchema,
|
state: executionWorkspaceCloseReadinessStateSchema,
|
||||||
|
|
@ -73,35 +103,7 @@ export const executionWorkspaceCloseReadinessSchema = z.object({
|
||||||
isSharedWorkspace: z.boolean(),
|
isSharedWorkspace: z.boolean(),
|
||||||
isProjectPrimaryWorkspace: z.boolean(),
|
isProjectPrimaryWorkspace: z.boolean(),
|
||||||
git: executionWorkspaceCloseGitReadinessSchema.nullable(),
|
git: executionWorkspaceCloseGitReadinessSchema.nullable(),
|
||||||
runtimeServices: z.array(z.object({
|
runtimeServices: z.array(workspaceRuntimeServiceSchema),
|
||||||
id: z.string(),
|
|
||||||
companyId: z.string().uuid(),
|
|
||||||
projectId: z.string().uuid().nullable(),
|
|
||||||
projectWorkspaceId: z.string().uuid().nullable(),
|
|
||||||
executionWorkspaceId: z.string().uuid().nullable(),
|
|
||||||
issueId: z.string().uuid().nullable(),
|
|
||||||
scopeType: z.enum(["project_workspace", "execution_workspace", "run", "agent"]),
|
|
||||||
scopeId: z.string().nullable(),
|
|
||||||
serviceName: z.string(),
|
|
||||||
status: z.enum(["starting", "running", "stopped", "failed"]),
|
|
||||||
lifecycle: z.enum(["shared", "ephemeral"]),
|
|
||||||
reuseKey: z.string().nullable(),
|
|
||||||
command: z.string().nullable(),
|
|
||||||
cwd: z.string().nullable(),
|
|
||||||
port: z.number().int().nullable(),
|
|
||||||
url: z.string().nullable(),
|
|
||||||
provider: z.enum(["local_process", "adapter_managed"]),
|
|
||||||
providerRef: z.string().nullable(),
|
|
||||||
ownerAgentId: z.string().uuid().nullable(),
|
|
||||||
startedByRunId: z.string().uuid().nullable(),
|
|
||||||
lastUsedAt: z.coerce.date(),
|
|
||||||
startedAt: z.coerce.date(),
|
|
||||||
stoppedAt: z.coerce.date().nullable(),
|
|
||||||
stopPolicy: z.record(z.unknown()).nullable(),
|
|
||||||
healthStatus: z.enum(["unknown", "healthy", "unhealthy"]),
|
|
||||||
createdAt: z.coerce.date(),
|
|
||||||
updatedAt: z.coerce.date(),
|
|
||||||
}).strict()),
|
|
||||||
}).strict();
|
}).strict();
|
||||||
|
|
||||||
export const updateExecutionWorkspaceSchema = z.object({
|
export const updateExecutionWorkspaceSchema = z.object({
|
||||||
|
|
|
||||||
|
|
@ -1192,6 +1192,8 @@ export function normalizeAdapterManagedRuntimeServices(input: {
|
||||||
async function startLocalRuntimeService(input: {
|
async function startLocalRuntimeService(input: {
|
||||||
db?: Db;
|
db?: Db;
|
||||||
runId: string;
|
runId: string;
|
||||||
|
leaseRunId?: string | null;
|
||||||
|
startedByRunId?: string | null;
|
||||||
agent: ExecutionWorkspaceAgentRef;
|
agent: ExecutionWorkspaceAgentRef;
|
||||||
issue: ExecutionWorkspaceIssueRef | null;
|
issue: ExecutionWorkspaceIssueRef | null;
|
||||||
workspace: RealizedExecutionWorkspace;
|
workspace: RealizedExecutionWorkspace;
|
||||||
|
|
@ -1203,6 +1205,8 @@ async function startLocalRuntimeService(input: {
|
||||||
scopeType: "project_workspace" | "execution_workspace" | "run" | "agent";
|
scopeType: "project_workspace" | "execution_workspace" | "run" | "agent";
|
||||||
scopeId: string | null;
|
scopeId: string | null;
|
||||||
}): Promise<RuntimeServiceRecord> {
|
}): Promise<RuntimeServiceRecord> {
|
||||||
|
const leaseRunId = input.leaseRunId === undefined ? input.runId : input.leaseRunId;
|
||||||
|
const startedByRunId = input.startedByRunId === undefined ? input.runId : input.startedByRunId;
|
||||||
const identity = resolveRuntimeServiceReuseIdentity({
|
const identity = resolveRuntimeServiceReuseIdentity({
|
||||||
service: input.service,
|
service: input.service,
|
||||||
workspace: input.workspace,
|
workspace: input.workspace,
|
||||||
|
|
@ -1299,7 +1303,7 @@ async function startLocalRuntimeService(input: {
|
||||||
provider: "local_process",
|
provider: "local_process",
|
||||||
providerRef: String(adoptedRecord.pid),
|
providerRef: String(adoptedRecord.pid),
|
||||||
ownerAgentId: input.agent.id ?? null,
|
ownerAgentId: input.agent.id ?? null,
|
||||||
startedByRunId: input.runId,
|
startedByRunId,
|
||||||
lastUsedAt: new Date().toISOString(),
|
lastUsedAt: new Date().toISOString(),
|
||||||
startedAt: adoptedRecord.startedAt,
|
startedAt: adoptedRecord.startedAt,
|
||||||
stoppedAt: null,
|
stoppedAt: null,
|
||||||
|
|
@ -1308,7 +1312,7 @@ async function startLocalRuntimeService(input: {
|
||||||
reused: true,
|
reused: true,
|
||||||
db: input.db,
|
db: input.db,
|
||||||
child: null,
|
child: null,
|
||||||
leaseRunIds: new Set([input.runId]),
|
leaseRunIds: leaseRunId ? new Set([leaseRunId]) : new Set(),
|
||||||
idleTimer: null,
|
idleTimer: null,
|
||||||
envFingerprint,
|
envFingerprint,
|
||||||
serviceKey,
|
serviceKey,
|
||||||
|
|
@ -1373,7 +1377,7 @@ async function startLocalRuntimeService(input: {
|
||||||
provider: "local_process",
|
provider: "local_process",
|
||||||
providerRef: child.pid ? String(child.pid) : null,
|
providerRef: child.pid ? String(child.pid) : null,
|
||||||
ownerAgentId: input.agent.id ?? null,
|
ownerAgentId: input.agent.id ?? null,
|
||||||
startedByRunId: input.runId,
|
startedByRunId,
|
||||||
lastUsedAt: new Date().toISOString(),
|
lastUsedAt: new Date().toISOString(),
|
||||||
startedAt: new Date().toISOString(),
|
startedAt: new Date().toISOString(),
|
||||||
stoppedAt: null,
|
stoppedAt: null,
|
||||||
|
|
@ -1382,7 +1386,7 @@ async function startLocalRuntimeService(input: {
|
||||||
reused: false,
|
reused: false,
|
||||||
db: input.db,
|
db: input.db,
|
||||||
child,
|
child,
|
||||||
leaseRunIds: new Set([input.runId]),
|
leaseRunIds: leaseRunId ? new Set([leaseRunId]) : new Set(),
|
||||||
idleTimer: null,
|
idleTimer: null,
|
||||||
envFingerprint,
|
envFingerprint,
|
||||||
serviceKey,
|
serviceKey,
|
||||||
|
|
@ -1648,9 +1652,13 @@ export async function startRuntimeServicesForWorkspaceControl(input: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually controlled services are not tied to a heartbeat run lifecycle, so they do not
|
||||||
|
// retain a run lease and never persist a startedByRunId foreign key.
|
||||||
const record = await startLocalRuntimeService({
|
const record = await startLocalRuntimeService({
|
||||||
db: input.db,
|
db: input.db,
|
||||||
runId: invocationId,
|
runId: invocationId,
|
||||||
|
leaseRunId: null,
|
||||||
|
startedByRunId: null,
|
||||||
agent: input.actor,
|
agent: input.actor,
|
||||||
issue: input.issue,
|
issue: input.issue,
|
||||||
workspace: input.workspace,
|
workspace: input.workspace,
|
||||||
|
|
@ -1662,7 +1670,6 @@ export async function startRuntimeServicesForWorkspaceControl(input: {
|
||||||
scopeType,
|
scopeType,
|
||||||
scopeId,
|
scopeId,
|
||||||
});
|
});
|
||||||
record.startedByRunId = null;
|
|
||||||
registerRuntimeService(input.db, record);
|
registerRuntimeService(input.db, record);
|
||||||
await persistRuntimeServiceRecord(input.db, record);
|
await persistRuntimeServiceRecord(input.db, record);
|
||||||
refs.push(toRuntimeServiceRef(record));
|
refs.push(toRuntimeServiceRef(record));
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,8 @@ export function ExecutionWorkspaceCloseDialog({
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-sm font-medium">Blocking reasons</h3>
|
<h3 className="text-sm font-medium">Blocking reasons</h3>
|
||||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||||
{readiness.blockingReasons.map((reason) => (
|
{readiness.blockingReasons.map((reason, idx) => (
|
||||||
<li key={reason} className="break-words rounded-lg border border-destructive/20 bg-destructive/5 px-3 py-2 text-destructive">
|
<li key={`blocking-${idx}`} className="break-words rounded-lg border border-destructive/20 bg-destructive/5 px-3 py-2 text-destructive">
|
||||||
{reason}
|
{reason}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
@ -162,8 +162,8 @@ export function ExecutionWorkspaceCloseDialog({
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-sm font-medium">Warnings</h3>
|
<h3 className="text-sm font-medium">Warnings</h3>
|
||||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||||
{readiness.warnings.map((warning) => (
|
{readiness.warnings.map((warning, idx) => (
|
||||||
<li key={warning} className="break-words rounded-lg border border-amber-500/20 bg-amber-500/5 px-3 py-2">
|
<li key={`warning-${idx}`} className="break-words rounded-lg border border-amber-500/20 bg-amber-500/5 px-3 py-2">
|
||||||
{warning}
|
{warning}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue