mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-21 01:01:46 +00:00
Merge remote-tracking branch 'origin/full-docker-defaults' into async-action-fixes
# Conflicts: # foundry/CLAUDE.md # foundry/packages/backend/src/actors/task/workbench.ts # foundry/packages/frontend/src/components/dev-panel.tsx # foundry/packages/frontend/src/components/mock-layout.tsx # justfile
This commit is contained in:
commit
14d5413f8a
30 changed files with 521 additions and 413 deletions
|
|
@ -146,14 +146,9 @@ export const task = actor({
|
|||
|
||||
async provision(c, cmd: InitializeCommand): Promise<{ ok: true }> {
|
||||
const self = selfTask(c);
|
||||
const result = await self.send(taskWorkflowQueueName("task.command.provision"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 30 * 60_000,
|
||||
await self.send(taskWorkflowQueueName("task.command.provision"), cmd ?? {}, {
|
||||
wait: false,
|
||||
});
|
||||
const response = expectQueueResponse<{ ok: boolean; error?: string }>(result);
|
||||
if (!response.ok) {
|
||||
throw new Error(response.error ?? "task provisioning failed");
|
||||
}
|
||||
return { ok: true };
|
||||
},
|
||||
|
||||
|
|
@ -182,47 +177,35 @@ export const task = actor({
|
|||
async push(c, cmd?: TaskActionCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.push"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 180_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
async sync(c, cmd?: TaskActionCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.sync"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 30_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
async merge(c, cmd?: TaskActionCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.merge"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 30_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
async archive(c, cmd?: TaskActionCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
void self
|
||||
.send(taskWorkflowQueueName("task.command.archive"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 60_000,
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
c.log.warn({
|
||||
msg: "archive command failed",
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
});
|
||||
await self.send(taskWorkflowQueueName("task.command.archive"), cmd ?? {}, {
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
async kill(c, cmd?: TaskActionCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.kill"), cmd ?? {}, {
|
||||
wait: true,
|
||||
timeout: 60_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -265,8 +248,7 @@ export const task = actor({
|
|||
async renameWorkbenchBranch(c, input: TaskWorkbenchRenameInput): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.workbench.rename_branch"), { value: input.value } satisfies TaskWorkbenchValueCommand, {
|
||||
wait: true,
|
||||
timeout: 5 * 60_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -345,8 +327,7 @@ export const task = actor({
|
|||
attachments: input.attachments,
|
||||
} satisfies TaskWorkbenchSendMessageCommand,
|
||||
{
|
||||
wait: true,
|
||||
timeout: 10 * 60_000,
|
||||
wait: false,
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
@ -354,8 +335,7 @@ export const task = actor({
|
|||
async stopWorkbenchSession(c, input: TaskTabCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.workbench.stop_session"), { sessionId: input.tabId } satisfies TaskWorkbenchSessionCommand, {
|
||||
wait: true,
|
||||
timeout: 5 * 60_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -370,8 +350,7 @@ export const task = actor({
|
|||
async closeWorkbenchSession(c, input: TaskTabCommand): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.workbench.close_session"), { sessionId: input.tabId } satisfies TaskWorkbenchSessionCommand, {
|
||||
wait: true,
|
||||
timeout: 5 * 60_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -381,8 +360,7 @@ export const task = actor({
|
|||
taskWorkflowQueueName("task.command.workbench.publish_pr"),
|
||||
{},
|
||||
{
|
||||
wait: true,
|
||||
timeout: 10 * 60_000,
|
||||
wait: false,
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
@ -390,8 +368,7 @@ export const task = actor({
|
|||
async revertWorkbenchFile(c, input: { path: string }): Promise<void> {
|
||||
const self = selfTask(c);
|
||||
await self.send(taskWorkflowQueueName("task.command.workbench.revert_file"), input, {
|
||||
wait: true,
|
||||
timeout: 5 * 60_000,
|
||||
wait: false,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { getOrCreateTaskStatusSync, getOrCreateProject, getOrCreateWorkspace, ge
|
|||
import { resolveWorkspaceGithubAuth } from "../../services/github-auth.js";
|
||||
import { task as taskTable, taskRuntime, taskWorkbenchSessions } from "./db/schema.js";
|
||||
import { getCurrentRecord } from "./workflow/common.js";
|
||||
import { taskWorkflowQueueName } from "./workflow/queue.js";
|
||||
|
||||
const STATUS_SYNC_INTERVAL_MS = 1_000;
|
||||
|
||||
|
|
@ -835,7 +836,14 @@ export async function renameWorkbenchBranch(c: any, value: string): Promise<void
|
|||
}
|
||||
|
||||
export async function createWorkbenchSession(c: any, model?: string): Promise<{ tabId: string }> {
|
||||
const record = await ensureWorkbenchSeeded(c);
|
||||
let record = await ensureWorkbenchSeeded(c);
|
||||
if (!record.activeSandboxId) {
|
||||
// Fire-and-forget: enqueue provisioning without waiting to avoid self-deadlock
|
||||
// (this handler already runs inside the task workflow loop, so wait:true would deadlock).
|
||||
const providerId = record.providerId ?? c.state.providerId ?? getActorRuntimeContext().providers.defaultProviderId();
|
||||
await selfTask(c).send(taskWorkflowQueueName("task.command.provision"), { providerId }, { wait: false });
|
||||
throw new Error("sandbox is provisioning — retry shortly");
|
||||
}
|
||||
|
||||
if (record.activeSessionId) {
|
||||
const existingSessions = await listSessionMetaRows(c);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!--
|
||||
<script src="https://unpkg.com/react-scan/dist/auto.global.js" crossorigin="anonymous"></script>
|
||||
<script type="module">
|
||||
if (import.meta.env.DEV) {
|
||||
import("react-grab");
|
||||
import("@react-grab/mcp/client");
|
||||
}
|
||||
</script>
|
||||
-->
|
||||
<script>if(window.__TAURI_INTERNALS__)document.documentElement.dataset.tauri="1"</script>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { TabStrip } from "./mock-layout/tab-strip";
|
|||
import { TerminalPane } from "./mock-layout/terminal-pane";
|
||||
import { TranscriptHeader } from "./mock-layout/transcript-header";
|
||||
import { PROMPT_TEXTAREA_MAX_HEIGHT, PROMPT_TEXTAREA_MIN_HEIGHT, SPanel, ScrollBody, Shell } from "./mock-layout/ui";
|
||||
import { DevPanel, useDevPanel } from "./dev-panel";
|
||||
import {
|
||||
buildDisplayMessages,
|
||||
diffPath,
|
||||
|
|
@ -1759,6 +1760,7 @@ export function MockLayout({ workspaceId, selectedTaskId, selectedSessionId }: M
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{showDevPanel && <DevPanel workspaceId={workspaceId} snapshot={viewModel} />}
|
||||
</Shell>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue