@benjamolina/pi-antigravity-guard 0.4.8 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context.d.ts +3 -0
- package/dist/context.js +27 -5
- package/dist/envelope.d.ts +20 -0
- package/dist/envelope.js +112 -0
- package/dist/tool-context.js +2 -1
- package/package.json +1 -1
package/dist/context.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface GenerationRequest {
|
|
|
26
26
|
request: {
|
|
27
27
|
contents: Content[];
|
|
28
28
|
systemInstruction?: {
|
|
29
|
+
role?: "user";
|
|
29
30
|
parts: Part[];
|
|
30
31
|
};
|
|
31
32
|
tools?: {
|
|
@@ -47,6 +48,8 @@ export interface GenerationRequest {
|
|
|
47
48
|
includeThoughts: boolean;
|
|
48
49
|
};
|
|
49
50
|
};
|
|
51
|
+
sessionId?: string;
|
|
52
|
+
labels?: Record<string, string>;
|
|
50
53
|
};
|
|
51
54
|
requestType: "agent";
|
|
52
55
|
userAgent: "antigravity";
|
package/dist/context.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CLAUDE_CUSTOM_PARAMETERS_PROFILE, getCatalogEntry, resolveGenerationSelection } from "./catalog.js";
|
|
2
2
|
import { normalizeCustomToolSchema } from "./tool-schema.js";
|
|
3
|
+
import { buildAntigravityEnvelope } from "./envelope.js";
|
|
3
4
|
import { hasToolContext, prepareToolContext, replayToolHistory } from "./tool-context.js";
|
|
4
5
|
const MAX_TEXT_BYTES = 8 * 1024 * 1024;
|
|
5
6
|
const PROVIDER = "antigravity-guard";
|
|
@@ -36,6 +37,13 @@ export function serializeContext(input, injectedSelection, onDiagnostics) {
|
|
|
36
37
|
} : undefined;
|
|
37
38
|
const contents = replayToolHistory(isDenseArray(messages), (part, message) => messagePart(part, field(message, "role") === "assistant", sameModel(message)), onDiagnostics, toolReplayPolicy, prepared?.declarations.length ?? 0);
|
|
38
39
|
const { systemInstruction, generationConfig } = text.request;
|
|
40
|
+
const envelope = buildAntigravityEnvelope({
|
|
41
|
+
wireModelId: selection.route.wireModel,
|
|
42
|
+
family: entry.response.family,
|
|
43
|
+
contentsCount: contents.length,
|
|
44
|
+
messages: isDenseArray(messages),
|
|
45
|
+
injectedRequestId: input.requestId,
|
|
46
|
+
});
|
|
39
47
|
return { ...text, request: {
|
|
40
48
|
contents,
|
|
41
49
|
...(systemInstruction ? { systemInstruction } : {}),
|
|
@@ -47,10 +55,16 @@ export function serializeContext(input, injectedSelection, onDiagnostics) {
|
|
|
47
55
|
? { parameters: normalizeCustomToolSchema(parameters) }
|
|
48
56
|
: { parametersJsonSchema: parameters }),
|
|
49
57
|
})) }],
|
|
50
|
-
...(prepared.mode === "NONE"
|
|
58
|
+
...(prepared.mode === "NONE"
|
|
59
|
+
? { toolConfig: { functionCallingConfig: { mode: "NONE" } } }
|
|
60
|
+
: (entry.response.family === "claude" || entry.response.family === "gpt-oss"
|
|
61
|
+
? { toolConfig: { functionCallingConfig: { mode: "AUTO" } } }
|
|
62
|
+
: {})),
|
|
51
63
|
} : {}),
|
|
52
64
|
generationConfig,
|
|
53
|
-
|
|
65
|
+
sessionId: envelope.sessionId,
|
|
66
|
+
labels: envelope.labels,
|
|
67
|
+
}, requestId: envelope.requestId };
|
|
54
68
|
}
|
|
55
69
|
export function serializeTextContext(input) {
|
|
56
70
|
try {
|
|
@@ -94,9 +108,16 @@ export function serializeTextContext(input) {
|
|
|
94
108
|
}
|
|
95
109
|
if (!contents.length)
|
|
96
110
|
fail("A text conversation is required.");
|
|
97
|
-
const systemInstruction = systemPrompt === undefined ? undefined : { parts: [{ text: systemPrompt }] };
|
|
111
|
+
const systemInstruction = systemPrompt === undefined ? undefined : { role: "user", parts: [{ text: systemPrompt }] };
|
|
98
112
|
const temperature = option(options, "temperature");
|
|
99
113
|
const maxTokens = option(options, "maxTokens");
|
|
114
|
+
const envelope = buildAntigravityEnvelope({
|
|
115
|
+
wireModelId: route.wireModel,
|
|
116
|
+
family: entry.response.family,
|
|
117
|
+
contentsCount: contents.length,
|
|
118
|
+
messages: isDenseArray(field(context, "messages", true)),
|
|
119
|
+
injectedRequestId: requestId,
|
|
120
|
+
});
|
|
100
121
|
return { project, model: route.wireModel, request: { contents, ...(systemInstruction ? { systemInstruction } : {}), generationConfig: {
|
|
101
122
|
temperature: typeof temperature === "number" ? temperature : 1,
|
|
102
123
|
maxOutputTokens: resolveOutputTokens(maxTokens, entry.descriptor.maxTokens, route.thinking),
|
|
@@ -104,7 +125,7 @@ export function serializeTextContext(input) {
|
|
|
104
125
|
const thinkingConfig = serializeThinkingConfig(route.thinking);
|
|
105
126
|
return thinkingConfig ? { thinkingConfig } : {};
|
|
106
127
|
})(),
|
|
107
|
-
} }, requestType: "agent", userAgent: "antigravity", requestId };
|
|
128
|
+
}, sessionId: envelope.sessionId, labels: envelope.labels }, requestType: "agent", userAgent: "antigravity", requestId: envelope.requestId };
|
|
108
129
|
}
|
|
109
130
|
catch (error) {
|
|
110
131
|
if (error instanceof ContextSerializationError)
|
|
@@ -175,7 +196,8 @@ function messagePart(part, assistant, sameProviderAndModel) {
|
|
|
175
196
|
fail("Invalid image data.");
|
|
176
197
|
const rawMime = field(part, "mimeType") ?? (isRecord(field(part, "source")) ? field(field(part, "source"), "media_type") : undefined);
|
|
177
198
|
const mimeType = typeof rawMime === "string" && rawMime ? rawMime : "image/jpeg";
|
|
178
|
-
|
|
199
|
+
const cleanedData = rawData.replace(/^data:[^;]+;base64,/s, "").trim();
|
|
200
|
+
return { inlineData: { mimeType, data: cleanedData } };
|
|
179
201
|
}
|
|
180
202
|
fail("Only text context is supported by this provider.");
|
|
181
203
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const ANTIGRAVITY_MODEL_ENUM: Readonly<Record<string, string>>;
|
|
2
|
+
export declare function stableUuid(seed: string): string;
|
|
3
|
+
export declare function resolveSessionTrajectory(messages?: readonly unknown[]): {
|
|
4
|
+
conversationId: string;
|
|
5
|
+
trajectoryId: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function clearSessionTrajectoryMap(): void;
|
|
8
|
+
export interface AntigravityEnvelope {
|
|
9
|
+
readonly requestId: string;
|
|
10
|
+
readonly sessionId: string;
|
|
11
|
+
readonly labels: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export declare function buildAntigravityEnvelope(options: {
|
|
14
|
+
wireModelId: string;
|
|
15
|
+
family: "gemini" | "claude" | "gpt-oss";
|
|
16
|
+
contentsCount: number;
|
|
17
|
+
messages?: readonly unknown[];
|
|
18
|
+
explicitSessionId?: string;
|
|
19
|
+
injectedRequestId?: string;
|
|
20
|
+
}): AntigravityEnvelope;
|
package/dist/envelope.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export const ANTIGRAVITY_MODEL_ENUM = Object.freeze({
|
|
3
|
+
// Gemini 3.8 Flash
|
|
4
|
+
"gemini-3.8-flash": "MODEL_PLACEHOLDER_M318",
|
|
5
|
+
"gemini-3.8-flash-high": "MODEL_PLACEHOLDER_M318",
|
|
6
|
+
"gemini-3.8-flash-medium": "MODEL_PLACEHOLDER_M319",
|
|
7
|
+
"gemini-3.8-flash-low": "MODEL_PLACEHOLDER_M320",
|
|
8
|
+
"gemini-3.8-flash-tiered": "MODEL_PLACEHOLDER_M322",
|
|
9
|
+
// Gemini 3.7 Flash
|
|
10
|
+
"gemini-3.7-flash": "MODEL_PLACEHOLDER_M298",
|
|
11
|
+
"gemini-3.7-flash-high": "MODEL_PLACEHOLDER_M298",
|
|
12
|
+
"gemini-3.7-flash-medium": "MODEL_PLACEHOLDER_M299",
|
|
13
|
+
"gemini-3.7-flash-low": "MODEL_PLACEHOLDER_M300",
|
|
14
|
+
"gemini-3.7-flash-tiered": "MODEL_PLACEHOLDER_M301",
|
|
15
|
+
// Gemini 3.6 Flash
|
|
16
|
+
"gemini-3.6-flash": "MODEL_PLACEHOLDER_M71",
|
|
17
|
+
"gemini-3.6-flash-high": "MODEL_PLACEHOLDER_M71",
|
|
18
|
+
"gemini-3.6-flash-medium": "MODEL_PLACEHOLDER_M72",
|
|
19
|
+
"gemini-3.6-flash-low": "MODEL_PLACEHOLDER_M73",
|
|
20
|
+
"gemini-3.6-flash-tiered": "MODEL_PLACEHOLDER_M196",
|
|
21
|
+
// Gemini 3.5 Flash
|
|
22
|
+
"gemini-3.5-flash": "MODEL_PLACEHOLDER_M20",
|
|
23
|
+
"gemini-3.5-flash-extra-low": "MODEL_PLACEHOLDER_M187",
|
|
24
|
+
"gemini-3.5-flash-low": "MODEL_PLACEHOLDER_M20",
|
|
25
|
+
"gemini-3-flash-agent": "MODEL_PLACEHOLDER_M84",
|
|
26
|
+
// Gemini 3.1 Pro
|
|
27
|
+
"gemini-3.1-pro": "MODEL_PLACEHOLDER_M36",
|
|
28
|
+
"gemini-3.1-pro-low": "MODEL_PLACEHOLDER_M36",
|
|
29
|
+
"gemini-3.1-pro-high": "MODEL_PLACEHOLDER_M37",
|
|
30
|
+
"gemini-pro-agent": "MODEL_PLACEHOLDER_M16",
|
|
31
|
+
// Claude
|
|
32
|
+
"claude-sonnet-4-6": "MODEL_PLACEHOLDER_M35",
|
|
33
|
+
"claude-opus-4-6": "MODEL_PLACEHOLDER_M26",
|
|
34
|
+
"claude-opus-4-6-thinking": "MODEL_PLACEHOLDER_M26",
|
|
35
|
+
// GPT-OSS
|
|
36
|
+
"gpt-oss-120b": "MODEL_OPENAI_GPT_OSS_120B_MEDIUM",
|
|
37
|
+
"gpt-oss-120b-medium": "MODEL_OPENAI_GPT_OSS_120B_MEDIUM",
|
|
38
|
+
});
|
|
39
|
+
export function stableUuid(seed) {
|
|
40
|
+
const bytes = createHash("sha1").update(seed).digest().subarray(0, 16);
|
|
41
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
42
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
43
|
+
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
44
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
45
|
+
}
|
|
46
|
+
const sessionTrajectoryMap = new Map();
|
|
47
|
+
export function resolveSessionTrajectory(messages) {
|
|
48
|
+
const firstMsg = Array.isArray(messages) ? messages[0] : undefined;
|
|
49
|
+
if (!isRecord(firstMsg)) {
|
|
50
|
+
return { conversationId: crypto.randomUUID(), trajectoryId: crypto.randomUUID() };
|
|
51
|
+
}
|
|
52
|
+
const role = typeof firstMsg.role === "string" ? firstMsg.role : "user";
|
|
53
|
+
const timestamp = typeof firstMsg.timestamp === "number" ? String(firstMsg.timestamp) : "";
|
|
54
|
+
const rawContent = firstMsg.content;
|
|
55
|
+
const contentSeed = typeof rawContent === "string"
|
|
56
|
+
? rawContent.slice(0, 64)
|
|
57
|
+
: Array.isArray(rawContent)
|
|
58
|
+
? JSON.stringify(rawContent[0] ?? "").slice(0, 64)
|
|
59
|
+
: "";
|
|
60
|
+
const seed = `${role}:${timestamp}:${contentSeed}`;
|
|
61
|
+
let entry = sessionTrajectoryMap.get(seed);
|
|
62
|
+
if (!entry) {
|
|
63
|
+
entry = {
|
|
64
|
+
conversationId: stableUuid(`antigravity:conv:${seed}`),
|
|
65
|
+
trajectoryId: stableUuid(`antigravity:traj:${seed}`),
|
|
66
|
+
};
|
|
67
|
+
sessionTrajectoryMap.set(seed, entry);
|
|
68
|
+
if (sessionTrajectoryMap.size > 64) {
|
|
69
|
+
const oldestKey = sessionTrajectoryMap.keys().next().value;
|
|
70
|
+
if (oldestKey !== undefined)
|
|
71
|
+
sessionTrajectoryMap.delete(oldestKey);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return entry;
|
|
75
|
+
}
|
|
76
|
+
export function clearSessionTrajectoryMap() {
|
|
77
|
+
sessionTrajectoryMap.clear();
|
|
78
|
+
}
|
|
79
|
+
const UUID_AGENT_REGEX = /^agent-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
80
|
+
export function buildAntigravityEnvelope(options) {
|
|
81
|
+
const isClaude = options.family === "claude";
|
|
82
|
+
const isNonGemini = options.family === "claude" || options.family === "gpt-oss";
|
|
83
|
+
const step = Math.max(1, options.contentsCount);
|
|
84
|
+
const lastStepIndex = String(Math.max(0, step - 1));
|
|
85
|
+
const assistantMsgCount = Array.isArray(options.messages)
|
|
86
|
+
? options.messages.filter((m) => isRecord(m) && m.role === "assistant" && m.stopReason !== "error" && m.stopReason !== "aborted").length
|
|
87
|
+
: 0;
|
|
88
|
+
const requestIndex = Math.max(0, assistantMsgCount);
|
|
89
|
+
const { conversationId, trajectoryId } = resolveSessionTrajectory(options.messages);
|
|
90
|
+
const sessionHash = createHash("sha1").update(`session:${trajectoryId}`).digest().subarray(0, 8);
|
|
91
|
+
const generatedSessionId = String(new DataView(sessionHash.buffer, sessionHash.byteOffset, 8).getBigInt64(0, true));
|
|
92
|
+
const sessionId = options.explicitSessionId || generatedSessionId;
|
|
93
|
+
const labels = {
|
|
94
|
+
last_step_index: lastStepIndex,
|
|
95
|
+
request_id: `${trajectoryId}-${requestIndex}`,
|
|
96
|
+
trajectory_id: trajectoryId,
|
|
97
|
+
used_claude: isClaude ? "true" : "false",
|
|
98
|
+
used_claude_conservative: isClaude ? "true" : "false",
|
|
99
|
+
used_non_gemini_model: isNonGemini ? "true" : "false",
|
|
100
|
+
};
|
|
101
|
+
const modelEnum = ANTIGRAVITY_MODEL_ENUM[options.wireModelId];
|
|
102
|
+
if (modelEnum) {
|
|
103
|
+
labels.model_enum = modelEnum;
|
|
104
|
+
}
|
|
105
|
+
const requestId = options.injectedRequestId && !UUID_AGENT_REGEX.test(options.injectedRequestId)
|
|
106
|
+
? options.injectedRequestId
|
|
107
|
+
: `agent/${conversationId}/${trajectoryId}/${step}`;
|
|
108
|
+
return { requestId, sessionId, labels };
|
|
109
|
+
}
|
|
110
|
+
function isRecord(value) {
|
|
111
|
+
return typeof value === "object" && value !== null;
|
|
112
|
+
}
|
package/dist/tool-context.js
CHANGED
|
@@ -105,7 +105,8 @@ export function replayToolHistory(messages, serializePart, onDiagnostics, policy
|
|
|
105
105
|
if (typeof rawData === "string" && rawData) {
|
|
106
106
|
const rawMime = value(part, "mimeType") ?? (isRecord(value(part, "source")) ? value(record(value(part, "source")), "media_type") : undefined);
|
|
107
107
|
const mimeType = typeof rawMime === "string" && rawMime ? rawMime : "image/jpeg";
|
|
108
|
-
|
|
108
|
+
const cleanedData = rawData.replace(/^data:[^;]+;base64,/s, "").trim();
|
|
109
|
+
imageParts.push({ inlineData: { mimeType, data: cleanedData } });
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
else {
|