File size: 1,423 Bytes
3d700dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { getActiveBackend } from "../backend-registry/active-store";
import type { Backend } from "../backend-registry/types";
import { callCloudProxy } from "./proxy";
import type { V1SandboxInfo } from "./sandbox-service.types";

function getActiveCloudBackend(): Backend {
  const active = getActiveBackend().backend;
  if (active.kind !== "cloud") {
    throw new Error("Cloud sandboxes call requires a cloud backend.");
  }
  return active;
}

/**
 * Batch-fetch cloud sandboxes by id. Mirrors OpenHands'
 * `SandboxService.batchGetSandboxes` by calling
 * `GET /api/v1/sandboxes?id=...` on the cloud backend, returning each
 * `SandboxInfo` (or null if not found).
 *
 * The returned `SandboxInfo.exposed_urls` carry the cloud-computed,
 * publicly-reachable URLs for the sandbox's services (VSCODE,
 * AGENT_SERVER, WORKER_*) — the GUI reads them directly instead of
 * asking the runtime for `/api/vscode/url`, which only knows its
 * internal localhost address.
 */
export async function batchGetCloudSandboxes(
  ids: string[],
): Promise<(V1SandboxInfo | null)[]> {
  if (ids.length === 0) return [];
  const backend = getActiveCloudBackend();
  const params = new URLSearchParams();
  for (const id of ids) params.append("id", id);
  const data = await callCloudProxy<(V1SandboxInfo | null)[]>({
    backend,
    method: "GET",
    path: `/api/v1/sandboxes?${params.toString()}`,
  });
  return data ?? [];
}