mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-20 02:03:19 +00:00
Workaround for RivetKit bug where c.queue.iter() never yields messages
for actors created via getOrCreate from another actor's context. The
queue accepts messages (visible in inspector) but the iterator hangs.
Sleep/wake fixes it, but actors with active connections never sleep.
Converted organization, github-data, task, and user actors from
run: workflow(...) to plain run: async (c) => { for await ... }.
Also fixes:
- Missing auth tables in org migration (auth_verification etc)
- default_model NOT NULL constraint on org profile upsert
- Nested workflow step in github-data (HistoryDivergedError)
- Removed --force from frontend Dockerfile pnpm install
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
311 lines
7.8 KiB
TypeScript
311 lines
7.8 KiB
TypeScript
import type { SandboxProviderId, TaskStatus } from "./contracts.js";
|
|
import type { WorkspaceAgentKind, WorkspaceModelGroup, WorkspaceModelId, WorkspaceModelOption } from "./models.js";
|
|
|
|
export type WorkspaceTaskStatus = TaskStatus;
|
|
export type WorkspaceSessionStatus = "pending_provision" | "pending_session_create" | "ready" | "running" | "idle" | "error";
|
|
|
|
export type { WorkspaceAgentKind, WorkspaceModelGroup, WorkspaceModelId, WorkspaceModelOption } from "./models.js";
|
|
|
|
export interface WorkspaceTranscriptEvent {
|
|
id: string;
|
|
eventIndex: number;
|
|
sessionId: string;
|
|
createdAt: number;
|
|
connectionId: string;
|
|
sender: "client" | "agent";
|
|
payload: unknown;
|
|
}
|
|
|
|
export interface WorkspaceComposerDraft {
|
|
text: string;
|
|
attachments: WorkspaceLineAttachment[];
|
|
updatedAtMs: number | null;
|
|
}
|
|
|
|
/** Session metadata without transcript content. */
|
|
export interface WorkspaceSessionSummary {
|
|
id: string;
|
|
/** Stable UI session id used for routing and task-local identity. */
|
|
sessionId: string;
|
|
/** Underlying sandbox session id when provisioning has completed. */
|
|
sandboxSessionId?: string | null;
|
|
sessionName: string;
|
|
agent: WorkspaceAgentKind;
|
|
model: WorkspaceModelId;
|
|
status: WorkspaceSessionStatus;
|
|
thinkingSinceMs: number | null;
|
|
unread: boolean;
|
|
created: boolean;
|
|
errorMessage?: string | null;
|
|
}
|
|
|
|
/** Full session content — only fetched when viewing a specific session. */
|
|
export interface WorkspaceSessionDetail {
|
|
/** Stable UI session id used for the session topic key and routing. */
|
|
sessionId: string;
|
|
sandboxSessionId: string | null;
|
|
sessionName: string;
|
|
agent: WorkspaceAgentKind;
|
|
model: WorkspaceModelId;
|
|
status: WorkspaceSessionStatus;
|
|
thinkingSinceMs: number | null;
|
|
unread: boolean;
|
|
created: boolean;
|
|
errorMessage?: string | null;
|
|
draft: WorkspaceComposerDraft;
|
|
transcript: WorkspaceTranscriptEvent[];
|
|
}
|
|
|
|
export interface WorkspaceFileChange {
|
|
path: string;
|
|
added: number;
|
|
removed: number;
|
|
type: "M" | "A" | "D";
|
|
}
|
|
|
|
export interface WorkspaceFileTreeNode {
|
|
name: string;
|
|
path: string;
|
|
isDir: boolean;
|
|
children?: WorkspaceFileTreeNode[];
|
|
}
|
|
|
|
export interface WorkspaceLineAttachment {
|
|
id: string;
|
|
filePath: string;
|
|
lineNumber: number;
|
|
lineContent: string;
|
|
}
|
|
|
|
export interface WorkspaceHistoryEvent {
|
|
id: string;
|
|
messageId: string;
|
|
preview: string;
|
|
sessionName: string;
|
|
sessionId: string;
|
|
createdAtMs: number;
|
|
detail: string;
|
|
}
|
|
|
|
export type WorkspaceDiffLineKind = "context" | "add" | "remove" | "hunk";
|
|
|
|
export interface WorkspaceParsedDiffLine {
|
|
kind: WorkspaceDiffLineKind;
|
|
lineNumber: number;
|
|
text: string;
|
|
}
|
|
|
|
export interface WorkspacePullRequestSummary {
|
|
number: number;
|
|
status: "draft" | "ready";
|
|
title?: string;
|
|
state?: string;
|
|
url?: string;
|
|
headRefName?: string;
|
|
baseRefName?: string;
|
|
repoFullName?: string;
|
|
authorLogin?: string | null;
|
|
isDraft?: boolean;
|
|
updatedAtMs?: number;
|
|
}
|
|
|
|
export interface WorkspaceSandboxSummary {
|
|
sandboxProviderId: SandboxProviderId;
|
|
sandboxId: string;
|
|
cwd: string | null;
|
|
}
|
|
|
|
/** Sidebar-level task data. Materialized in the organization actor's SQLite. */
|
|
export interface WorkspaceTaskSummary {
|
|
id: string;
|
|
repoId: string;
|
|
title: string;
|
|
status: WorkspaceTaskStatus;
|
|
repoName: string;
|
|
updatedAtMs: number;
|
|
branch: string | null;
|
|
pullRequest: WorkspacePullRequestSummary | null;
|
|
activeSessionId: string | null;
|
|
/** Summary of sessions — no transcript content. */
|
|
sessionsSummary: WorkspaceSessionSummary[];
|
|
}
|
|
|
|
/** Full task detail — only fetched when viewing a specific task. */
|
|
export interface WorkspaceTaskDetail extends WorkspaceTaskSummary {
|
|
/** Original task prompt/instructions shown in the detail view. */
|
|
task: string;
|
|
fileChanges: WorkspaceFileChange[];
|
|
diffs: Record<string, string>;
|
|
fileTree: WorkspaceFileTreeNode[];
|
|
minutesUsed: number;
|
|
/** Sandbox info for this task. */
|
|
sandboxes: WorkspaceSandboxSummary[];
|
|
activeSandboxId: string | null;
|
|
}
|
|
|
|
/** Repo-level summary for organization sidebar. */
|
|
export interface WorkspaceRepositorySummary {
|
|
id: string;
|
|
label: string;
|
|
/** Aggregated branch/task overview state (replaces getRepoOverview polling). */
|
|
taskCount: number;
|
|
latestActivityMs: number;
|
|
}
|
|
|
|
export type OrganizationGithubSyncPhase =
|
|
| "discovering_repositories"
|
|
| "syncing_repositories"
|
|
| "syncing_branches"
|
|
| "syncing_members"
|
|
| "syncing_pull_requests";
|
|
|
|
export interface OrganizationGithubSummary {
|
|
connectedAccount: string;
|
|
installationStatus: "connected" | "install_required" | "reconnect_required";
|
|
syncStatus: "pending" | "syncing" | "synced" | "error";
|
|
importedRepoCount: number;
|
|
lastSyncLabel: string;
|
|
lastSyncAt: number | null;
|
|
lastWebhookAt: number | null;
|
|
lastWebhookEvent: string;
|
|
syncGeneration: number;
|
|
syncPhase: OrganizationGithubSyncPhase | null;
|
|
processedRepositoryCount: number;
|
|
totalRepositoryCount: number;
|
|
}
|
|
|
|
export interface WorkspaceOpenPullRequest {
|
|
repoId: string;
|
|
repoFullName: string;
|
|
number: number;
|
|
title: string;
|
|
status: string;
|
|
state: string;
|
|
url: string;
|
|
headRefName: string;
|
|
baseRefName: string;
|
|
authorLogin: string | null;
|
|
isDraft: boolean;
|
|
}
|
|
|
|
/** Organization-level snapshot — initial fetch for the organization topic. */
|
|
export interface OrganizationSummarySnapshot {
|
|
organizationId: string;
|
|
github: OrganizationGithubSummary;
|
|
repos: WorkspaceRepositorySummary[];
|
|
taskSummaries: WorkspaceTaskSummary[];
|
|
openPullRequests?: WorkspaceOpenPullRequest[];
|
|
}
|
|
|
|
export interface WorkspaceSession extends WorkspaceSessionSummary {
|
|
draft: WorkspaceComposerDraft;
|
|
transcript: WorkspaceTranscriptEvent[];
|
|
}
|
|
|
|
export interface WorkspaceTask {
|
|
id: string;
|
|
repoId: string;
|
|
title: string;
|
|
status: WorkspaceTaskStatus;
|
|
repoName: string;
|
|
updatedAtMs: number;
|
|
branch: string | null;
|
|
pullRequest: WorkspacePullRequestSummary | null;
|
|
activeSessionId?: string | null;
|
|
sessions: WorkspaceSession[];
|
|
fileChanges: WorkspaceFileChange[];
|
|
diffs: Record<string, string>;
|
|
fileTree: WorkspaceFileTreeNode[];
|
|
minutesUsed: number;
|
|
activeSandboxId?: string | null;
|
|
}
|
|
|
|
export interface WorkspaceRepo {
|
|
id: string;
|
|
label: string;
|
|
}
|
|
|
|
export interface WorkspaceRepositorySection {
|
|
id: string;
|
|
label: string;
|
|
updatedAtMs: number;
|
|
tasks: WorkspaceTask[];
|
|
}
|
|
|
|
export interface TaskWorkspaceSnapshot {
|
|
organizationId: string;
|
|
repos: WorkspaceRepo[];
|
|
repositories: WorkspaceRepositorySection[];
|
|
tasks: WorkspaceTask[];
|
|
}
|
|
|
|
export interface TaskWorkspaceSelectInput {
|
|
repoId: string;
|
|
taskId: string;
|
|
authSessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceCreateTaskInput {
|
|
repoId: string;
|
|
task: string;
|
|
title?: string;
|
|
branch?: string;
|
|
onBranch?: string;
|
|
model?: WorkspaceModelId;
|
|
authSessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceRenameInput {
|
|
repoId: string;
|
|
taskId: string;
|
|
value: string;
|
|
authSessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceSendMessageInput {
|
|
repoId: string;
|
|
taskId: string;
|
|
sessionId: string;
|
|
text: string;
|
|
attachments: WorkspaceLineAttachment[];
|
|
authSessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceSessionInput {
|
|
repoId: string;
|
|
taskId: string;
|
|
sessionId: string;
|
|
authSessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceRenameSessionInput extends TaskWorkspaceSessionInput {
|
|
title: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceChangeModelInput extends TaskWorkspaceSessionInput {
|
|
model: WorkspaceModelId;
|
|
}
|
|
|
|
export interface TaskWorkspaceUpdateDraftInput extends TaskWorkspaceSessionInput {
|
|
text: string;
|
|
attachments: WorkspaceLineAttachment[];
|
|
}
|
|
|
|
export interface TaskWorkspaceSetSessionUnreadInput extends TaskWorkspaceSessionInput {
|
|
unread: boolean;
|
|
}
|
|
|
|
export interface TaskWorkspaceDiffInput {
|
|
repoId: string;
|
|
taskId: string;
|
|
path: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceCreateTaskResponse {
|
|
taskId: string;
|
|
sessionId?: string;
|
|
}
|
|
|
|
export interface TaskWorkspaceAddSessionResponse {
|
|
sessionId: string;
|
|
}
|