mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-19 21:00:33 +00:00
Integrate OpenHandoff factory workspace (#212)
This commit is contained in:
parent
3d9476ed0b
commit
bf282199b5
251 changed files with 42824 additions and 692 deletions
180
factory/packages/backend/src/driver.ts
Normal file
180
factory/packages/backend/src/driver.ts
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import type { BranchSnapshot } from "./integrations/git/index.js";
|
||||
import type { PullRequestSnapshot } from "./integrations/github/index.js";
|
||||
import type {
|
||||
SandboxSession,
|
||||
SandboxAgentClientOptions,
|
||||
SandboxSessionCreateRequest
|
||||
} from "./integrations/sandbox-agent/client.js";
|
||||
import type { ListEventsRequest, ListPage, ListPageRequest, SessionEvent, SessionRecord } from "sandbox-agent";
|
||||
import type {
|
||||
DaytonaClientOptions,
|
||||
DaytonaCreateSandboxOptions,
|
||||
DaytonaPreviewEndpoint,
|
||||
DaytonaSandbox,
|
||||
} from "./integrations/daytona/client.js";
|
||||
import {
|
||||
validateRemote,
|
||||
ensureCloned,
|
||||
fetch,
|
||||
listRemoteBranches,
|
||||
remoteDefaultBaseRef,
|
||||
revParse,
|
||||
ensureRemoteBranch,
|
||||
diffStatForBranch,
|
||||
conflictsWithMain,
|
||||
} from "./integrations/git/index.js";
|
||||
import {
|
||||
gitSpiceAvailable,
|
||||
gitSpiceListStack,
|
||||
gitSpiceRebaseBranch,
|
||||
gitSpiceReparentBranch,
|
||||
gitSpiceRestackRepo,
|
||||
gitSpiceRestackSubtree,
|
||||
gitSpiceSyncRepo,
|
||||
gitSpiceTrackBranch,
|
||||
} from "./integrations/git-spice/index.js";
|
||||
import { listPullRequests, createPr } from "./integrations/github/index.js";
|
||||
import { SandboxAgentClient } from "./integrations/sandbox-agent/client.js";
|
||||
import { DaytonaClient } from "./integrations/daytona/client.js";
|
||||
|
||||
export interface GitDriver {
|
||||
validateRemote(remoteUrl: string): Promise<void>;
|
||||
ensureCloned(remoteUrl: string, targetPath: string): Promise<void>;
|
||||
fetch(repoPath: string): Promise<void>;
|
||||
listRemoteBranches(repoPath: string): Promise<BranchSnapshot[]>;
|
||||
remoteDefaultBaseRef(repoPath: string): Promise<string>;
|
||||
revParse(repoPath: string, ref: string): Promise<string>;
|
||||
ensureRemoteBranch(repoPath: string, branchName: string): Promise<void>;
|
||||
diffStatForBranch(repoPath: string, branchName: string): Promise<string>;
|
||||
conflictsWithMain(repoPath: string, branchName: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface StackBranchSnapshot {
|
||||
branchName: string;
|
||||
parentBranch: string | null;
|
||||
}
|
||||
|
||||
export interface StackDriver {
|
||||
available(repoPath: string): Promise<boolean>;
|
||||
listStack(repoPath: string): Promise<StackBranchSnapshot[]>;
|
||||
syncRepo(repoPath: string): Promise<void>;
|
||||
restackRepo(repoPath: string): Promise<void>;
|
||||
restackSubtree(repoPath: string, branchName: string): Promise<void>;
|
||||
rebaseBranch(repoPath: string, branchName: string): Promise<void>;
|
||||
reparentBranch(repoPath: string, branchName: string, parentBranch: string): Promise<void>;
|
||||
trackBranch(repoPath: string, branchName: string, parentBranch: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface GithubDriver {
|
||||
listPullRequests(repoPath: string): Promise<PullRequestSnapshot[]>;
|
||||
createPr(
|
||||
repoPath: string,
|
||||
headBranch: string,
|
||||
title: string,
|
||||
body?: string
|
||||
): Promise<{ number: number; url: string }>;
|
||||
}
|
||||
|
||||
export interface SandboxAgentClientLike {
|
||||
createSession(request: string | SandboxSessionCreateRequest): Promise<SandboxSession>;
|
||||
sessionStatus(sessionId: string): Promise<SandboxSession>;
|
||||
listSessions(request?: ListPageRequest): Promise<ListPage<SessionRecord>>;
|
||||
listEvents(request: ListEventsRequest): Promise<ListPage<SessionEvent>>;
|
||||
sendPrompt(request: { sessionId: string; prompt: string; notification?: boolean }): Promise<void>;
|
||||
cancelSession(sessionId: string): Promise<void>;
|
||||
destroySession(sessionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface SandboxAgentDriver {
|
||||
createClient(options: SandboxAgentClientOptions): SandboxAgentClientLike;
|
||||
}
|
||||
|
||||
export interface DaytonaClientLike {
|
||||
createSandbox(options: DaytonaCreateSandboxOptions): Promise<DaytonaSandbox>;
|
||||
getSandbox(sandboxId: string): Promise<DaytonaSandbox>;
|
||||
startSandbox(sandboxId: string, timeoutSeconds?: number): Promise<void>;
|
||||
stopSandbox(sandboxId: string, timeoutSeconds?: number): Promise<void>;
|
||||
deleteSandbox(sandboxId: string): Promise<void>;
|
||||
executeCommand(sandboxId: string, command: string): Promise<{ exitCode: number; result: string }>;
|
||||
getPreviewEndpoint(sandboxId: string, port: number): Promise<DaytonaPreviewEndpoint>;
|
||||
}
|
||||
|
||||
export interface DaytonaDriver {
|
||||
createClient(options: DaytonaClientOptions): DaytonaClientLike;
|
||||
}
|
||||
|
||||
export interface TmuxDriver {
|
||||
setWindowStatus(branchName: string, status: string): number;
|
||||
}
|
||||
|
||||
export interface BackendDriver {
|
||||
git: GitDriver;
|
||||
stack: StackDriver;
|
||||
github: GithubDriver;
|
||||
sandboxAgent: SandboxAgentDriver;
|
||||
daytona: DaytonaDriver;
|
||||
tmux: TmuxDriver;
|
||||
}
|
||||
|
||||
export function createDefaultDriver(): BackendDriver {
|
||||
const sandboxAgentClients = new Map<string, SandboxAgentClient>();
|
||||
const daytonaClients = new Map<string, DaytonaClient>();
|
||||
|
||||
return {
|
||||
git: {
|
||||
validateRemote,
|
||||
ensureCloned,
|
||||
fetch,
|
||||
listRemoteBranches,
|
||||
remoteDefaultBaseRef,
|
||||
revParse,
|
||||
ensureRemoteBranch,
|
||||
diffStatForBranch,
|
||||
conflictsWithMain,
|
||||
},
|
||||
stack: {
|
||||
available: gitSpiceAvailable,
|
||||
listStack: gitSpiceListStack,
|
||||
syncRepo: gitSpiceSyncRepo,
|
||||
restackRepo: gitSpiceRestackRepo,
|
||||
restackSubtree: gitSpiceRestackSubtree,
|
||||
rebaseBranch: gitSpiceRebaseBranch,
|
||||
reparentBranch: gitSpiceReparentBranch,
|
||||
trackBranch: gitSpiceTrackBranch,
|
||||
},
|
||||
github: {
|
||||
listPullRequests,
|
||||
createPr,
|
||||
},
|
||||
sandboxAgent: {
|
||||
createClient: (opts) => {
|
||||
if (opts.persist) {
|
||||
return new SandboxAgentClient(opts);
|
||||
}
|
||||
const key = `${opts.endpoint}|${opts.token ?? ""}|${opts.agent ?? ""}`;
|
||||
const cached = sandboxAgentClients.get(key);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const created = new SandboxAgentClient(opts);
|
||||
sandboxAgentClients.set(key, created);
|
||||
return created;
|
||||
},
|
||||
},
|
||||
daytona: {
|
||||
createClient: (opts) => {
|
||||
const key = `${opts.apiUrl ?? ""}|${opts.apiKey ?? ""}|${opts.target ?? ""}`;
|
||||
const cached = daytonaClients.get(key);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const created = new DaytonaClient(opts);
|
||||
daytonaClients.set(key, created);
|
||||
return created;
|
||||
},
|
||||
},
|
||||
tmux: {
|
||||
setWindowStatus: () => 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue