File size: 2,217 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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { CloudClient } from "@openhands/typescript-client/clients";
import {
  getAgentServerBaseUrl,
  getAgentServerHeaders,
} from "../agent-server-config";
import { NoBackendAvailableError } from "../agent-server-client-options";
import { getActiveBackend } from "../backend-registry/active-store";
import type { Backend } from "../backend-registry/types";

function requireCloudBackend(backend?: Backend): Backend {
  if (backend) return backend;
  const active = getActiveBackend().backend;
  if (active.kind !== "cloud") {
    throw new Error("Cloud calls require a cloud backend.");
  }
  return active;
}

/**
 * Send `X-Org-Id` so the upstream scopes per-request to the org the user
 * selected locally, instead of the user's globally-shared `current_org_id`
 * on the cloud backend. Restricted to calls against the active backend: the
 * selector also fans out per-backend bookkeeping calls (e.g.
 * `getCloudOrganizations(b)`) that would otherwise carry the active
 * backend's orgId across an unrelated API key, which the cloud backend
 * rejects when api_key_org_id and X-Org-Id disagree.
 */
function activeOrgForBackend(backend: Backend): string | null {
  const active = getActiveBackend();
  return active.backend.id === backend.id ? active.orgId : null;
}

export function createCloudClient(backend?: Backend): CloudClient {
  const target = requireCloudBackend(backend);
  const proxyBaseUrl = getAgentServerBaseUrl();
  const proxyHeaders = proxyBaseUrl ? getAgentServerHeaders() : {};

  return new CloudClient({
    host: target.host,
    apiKey: target.apiKey,
    orgId: activeOrgForBackend(target),
    // Default request timeout in ms, matching the 30s the previous axios
    // transport used for direct and proxied calls. Per-request
    // `timeoutSeconds` still overrides it for direct calls.
    timeout: 30_000,
    ...(proxyBaseUrl
      ? {
          proxy: {
            host: proxyBaseUrl,
            headers: proxyHeaders,
          },
        }
      : {}),
  });
}

export function createCloudClientForRuntime(backend?: Backend): CloudClient {
  const client = createCloudClient(backend);
  if (!client.proxy) {
    throw new NoBackendAvailableError();
  }
  return client;
}