File size: 1,977 Bytes
cd8bd0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use strict";

// =========================================================================
// Decide where the standalone proxy (server.cjs) forwards an intercepted,
// decrypted request — and which router endpoint speaks its wire format.
//
// The Antigravity IDE sends a cloudcode envelope:
//   { model, project, request: { contents, systemInstruction, tools, ... } }
// and expects a cloudcode SSE reply ({ response: { candidates, ... } }).
// That envelope is forwarded to the antigravity-compatible endpoint
// (/v1/antigravity), where the pipeline translates request antigravity→openai
// and response openai→antigravity, so the IDE gets its own format back
// regardless of which provider actually served it.
//
// Plain OpenAI bodies ({ messages: [...] }) keep going to /v1/chat/completions.
//
// Pure + deterministic so it is unit-testable without the proxy.
// =========================================================================

const CHAT_PATH = "/v1/chat/completions";
const ANTIGRAVITY_PATH = "/v1/antigravity";

/**
 * True when the parsed body is an Antigravity/cloudcode envelope (the IDE wraps
 * the Gemini-style payload under `request`, with a `contents` array).
 */
function isCloudcodeEnvelope(body) {
  return !!(
    body &&
    typeof body === "object" &&
    !Array.isArray(body) &&
    body.request &&
    typeof body.request === "object" &&
    Array.isArray(body.request.contents)
  );
}

/**
 * Resolve the forward URL + the format the IDE expects back. `baseUrl` is the
 * router base (e.g. http://localhost:20128); trailing slashes are trimmed.
 */
function resolveForwardTarget(baseUrl, body) {
  const base = String(baseUrl || "").replace(/\/+$/, "");
  if (isCloudcodeEnvelope(body)) {
    return { url: `${base}${ANTIGRAVITY_PATH}`, format: "antigravity" };
  }
  return { url: `${base}${CHAT_PATH}`, format: "openai" };
}

module.exports = {
  resolveForwardTarget,
  isCloudcodeEnvelope,
  CHAT_PATH,
  ANTIGRAVITY_PATH,
};