mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-16 03:02:03 +00:00
factory: rename project and handoff actors
This commit is contained in:
parent
3022bce2ad
commit
ea7c36a8e7
147 changed files with 6313 additions and 14364 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import type { HandoffRecord, HistoryEvent } from "@sandbox-agent/factory-shared";
|
||||
import type { TaskRecord, HistoryEvent } from "@sandbox-agent/factory-shared";
|
||||
import { createBackendClient } from "../../src/backend-client.js";
|
||||
|
||||
const RUN_E2E = process.env.HF_ENABLE_DAEMON_E2E === "1";
|
||||
|
|
@ -79,20 +79,20 @@ function parseHistoryPayload(event: HistoryEvent): Record<string, unknown> {
|
|||
}
|
||||
}
|
||||
|
||||
async function debugDump(client: ReturnType<typeof createBackendClient>, workspaceId: string, handoffId: string): Promise<string> {
|
||||
async function debugDump(client: ReturnType<typeof createBackendClient>, workspaceId: string, taskId: string): Promise<string> {
|
||||
try {
|
||||
const handoff = await client.getHandoff(workspaceId, handoffId);
|
||||
const history = await client.listHistory({ workspaceId, handoffId, limit: 80 }).catch(() => []);
|
||||
const task = await client.getTask(workspaceId, taskId);
|
||||
const history = await client.listHistory({ workspaceId, taskId, limit: 80 }).catch(() => []);
|
||||
const historySummary = history
|
||||
.slice(0, 20)
|
||||
.map((e) => `${new Date(e.createdAt).toISOString()} ${e.kind}`)
|
||||
.join("\n");
|
||||
|
||||
let sessionEventsSummary = "";
|
||||
if (handoff.activeSandboxId && handoff.activeSessionId) {
|
||||
if (task.activeSandboxId && task.activeSessionId) {
|
||||
const events = await client
|
||||
.listSandboxSessionEvents(workspaceId, handoff.providerId, handoff.activeSandboxId, {
|
||||
sessionId: handoff.activeSessionId,
|
||||
.listSandboxSessionEvents(workspaceId, task.providerId, task.activeSandboxId, {
|
||||
sessionId: task.activeSessionId,
|
||||
limit: 50,
|
||||
})
|
||||
.then((r) => r.items)
|
||||
|
|
@ -104,17 +104,17 @@ async function debugDump(client: ReturnType<typeof createBackendClient>, workspa
|
|||
}
|
||||
|
||||
return [
|
||||
"=== handoff ===",
|
||||
"=== task ===",
|
||||
JSON.stringify(
|
||||
{
|
||||
status: handoff.status,
|
||||
statusMessage: handoff.statusMessage,
|
||||
title: handoff.title,
|
||||
branchName: handoff.branchName,
|
||||
activeSandboxId: handoff.activeSandboxId,
|
||||
activeSessionId: handoff.activeSessionId,
|
||||
prUrl: handoff.prUrl,
|
||||
prSubmitted: handoff.prSubmitted,
|
||||
status: task.status,
|
||||
statusMessage: task.statusMessage,
|
||||
title: task.title,
|
||||
branchName: task.branchName,
|
||||
activeSandboxId: task.activeSandboxId,
|
||||
activeSessionId: task.activeSessionId,
|
||||
prUrl: task.prUrl,
|
||||
prSubmitted: task.prSubmitted,
|
||||
},
|
||||
null,
|
||||
2
|
||||
|
|
@ -144,7 +144,7 @@ async function githubApi(token: string, path: string, init?: RequestInit): Promi
|
|||
|
||||
describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
||||
it.skipIf(!RUN_E2E)(
|
||||
"creates a handoff, waits for agent to implement, and opens a PR",
|
||||
"creates a task, waits for agent to implement, and opens a PR",
|
||||
{ timeout: 15 * 60_000 },
|
||||
async () => {
|
||||
const endpoint =
|
||||
|
|
@ -164,7 +164,7 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
|
||||
const repo = await client.addRepo(workspaceId, repoRemote);
|
||||
|
||||
const created = await client.createHandoff({
|
||||
const created = await client.createTask({
|
||||
workspaceId,
|
||||
repoId: repo.repoId,
|
||||
task: [
|
||||
|
|
@ -187,42 +187,42 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
let lastStatus: string | null = null;
|
||||
|
||||
try {
|
||||
const namedAndProvisioned = await poll<HandoffRecord>(
|
||||
"handoff naming + sandbox provisioning",
|
||||
const namedAndProvisioned = await poll<TaskRecord>(
|
||||
"task naming + sandbox provisioning",
|
||||
// Cold Daytona snapshot/image preparation can exceed 5 minutes on first run.
|
||||
8 * 60_000,
|
||||
1_000,
|
||||
async () => client.getHandoff(workspaceId, created.handoffId),
|
||||
async () => client.getTask(workspaceId, created.taskId),
|
||||
(h) => Boolean(h.title && h.branchName && h.activeSandboxId),
|
||||
(h) => {
|
||||
if (h.status !== lastStatus) {
|
||||
lastStatus = h.status;
|
||||
}
|
||||
if (h.status === "error") {
|
||||
throw new Error("handoff entered error state during provisioning");
|
||||
throw new Error("task entered error state during provisioning");
|
||||
}
|
||||
}
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
});
|
||||
|
||||
branchName = namedAndProvisioned.branchName!;
|
||||
sandboxId = namedAndProvisioned.activeSandboxId!;
|
||||
|
||||
const withSession = await poll<HandoffRecord>(
|
||||
"handoff to create active session",
|
||||
const withSession = await poll<TaskRecord>(
|
||||
"task to create active session",
|
||||
3 * 60_000,
|
||||
1_500,
|
||||
async () => client.getHandoff(workspaceId, created.handoffId),
|
||||
async () => client.getTask(workspaceId, created.taskId),
|
||||
(h) => Boolean(h.activeSessionId),
|
||||
(h) => {
|
||||
if (h.status === "error") {
|
||||
throw new Error("handoff entered error state while waiting for active session");
|
||||
throw new Error("task entered error state while waiting for active session");
|
||||
}
|
||||
}
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
});
|
||||
|
||||
|
|
@ -241,23 +241,23 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
).items,
|
||||
(events) => events.length > 0
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
});
|
||||
|
||||
await poll<HandoffRecord>(
|
||||
"handoff to reach idle state",
|
||||
await poll<TaskRecord>(
|
||||
"task to reach idle state",
|
||||
8 * 60_000,
|
||||
2_000,
|
||||
async () => client.getHandoff(workspaceId, created.handoffId),
|
||||
async () => client.getTask(workspaceId, created.taskId),
|
||||
(h) => h.status === "idle",
|
||||
(h) => {
|
||||
if (h.status === "error") {
|
||||
throw new Error("handoff entered error state while waiting for idle");
|
||||
throw new Error("task entered error state while waiting for idle");
|
||||
}
|
||||
}
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
});
|
||||
|
||||
|
|
@ -265,14 +265,14 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
"PR creation history event",
|
||||
3 * 60_000,
|
||||
2_000,
|
||||
async () => client.listHistory({ workspaceId, handoffId: created.handoffId, limit: 200 }),
|
||||
(events) => events.some((e) => e.kind === "handoff.pr_created")
|
||||
async () => client.listHistory({ workspaceId, taskId: created.taskId, limit: 200 }),
|
||||
(events) => events.some((e) => e.kind === "task.pr_created")
|
||||
)
|
||||
.catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
})
|
||||
.then((events) => events.find((e) => e.kind === "handoff.pr_created")!);
|
||||
.then((events) => events.find((e) => e.kind === "task.pr_created")!);
|
||||
|
||||
const payload = parseHistoryPayload(prCreatedEvent);
|
||||
prNumber = Number(payload.prNumber);
|
||||
|
|
@ -293,17 +293,17 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
const prFiles = (await prFilesRes.json()) as Array<{ filename: string }>;
|
||||
expect(prFiles.some((f) => f.filename === expectedFile)).toBe(true);
|
||||
|
||||
// Close the handoff and assert the sandbox is released (stopped).
|
||||
await client.runAction(workspaceId, created.handoffId, "archive");
|
||||
// Close the task and assert the sandbox is released (stopped).
|
||||
await client.runAction(workspaceId, created.taskId, "archive");
|
||||
|
||||
await poll<HandoffRecord>(
|
||||
"handoff to become archived (session released)",
|
||||
await poll<TaskRecord>(
|
||||
"task to become archived (session released)",
|
||||
60_000,
|
||||
1_000,
|
||||
async () => client.getHandoff(workspaceId, created.handoffId),
|
||||
async () => client.getTask(workspaceId, created.taskId),
|
||||
(h) => h.status === "archived" && h.activeSessionId === null
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
throw new Error(`${err instanceof Error ? err.message : String(err)}\n${dump}`);
|
||||
});
|
||||
|
||||
|
|
@ -318,7 +318,7 @@ describe("e2e: backend -> sandbox-agent -> git -> PR", () => {
|
|||
return st.includes("stopped") || st.includes("suspended") || st.includes("paused");
|
||||
}
|
||||
).catch(async (err) => {
|
||||
const dump = await debugDump(client, workspaceId, created.handoffId);
|
||||
const dump = await debugDump(client, workspaceId, created.taskId);
|
||||
const state = await client
|
||||
.sandboxProviderState(workspaceId, "daytona", sandboxId!)
|
||||
.catch(() => null);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue