@benjamolina/pi-antigravity-guard 0.4.8 → 0.4.9

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 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 } : {}),
@@ -50,7 +58,9 @@ export function serializeContext(input, injectedSelection, onDiagnostics) {
50
58
  ...(prepared.mode === "NONE" ? { toolConfig: { functionCallingConfig: { mode: "NONE" } } } : {}),
51
59
  } : {}),
52
60
  generationConfig,
53
- } };
61
+ sessionId: envelope.sessionId,
62
+ labels: envelope.labels,
63
+ }, requestId: envelope.requestId };
54
64
  }
55
65
  export function serializeTextContext(input) {
56
66
  try {
@@ -94,9 +104,16 @@ export function serializeTextContext(input) {
94
104
  }
95
105
  if (!contents.length)
96
106
  fail("A text conversation is required.");
97
- const systemInstruction = systemPrompt === undefined ? undefined : { parts: [{ text: systemPrompt }] };
107
+ const systemInstruction = systemPrompt === undefined ? undefined : { role: "user", parts: [{ text: systemPrompt }] };
98
108
  const temperature = option(options, "temperature");
99
109
  const maxTokens = option(options, "maxTokens");
110
+ const envelope = buildAntigravityEnvelope({
111
+ wireModelId: route.wireModel,
112
+ family: entry.response.family,
113
+ contentsCount: contents.length,
114
+ messages: isDenseArray(field(context, "messages", true)),
115
+ injectedRequestId: requestId,
116
+ });
100
117
  return { project, model: route.wireModel, request: { contents, ...(systemInstruction ? { systemInstruction } : {}), generationConfig: {
101
118
  temperature: typeof temperature === "number" ? temperature : 1,
102
119
  maxOutputTokens: resolveOutputTokens(maxTokens, entry.descriptor.maxTokens, route.thinking),
@@ -104,7 +121,7 @@ export function serializeTextContext(input) {
104
121
  const thinkingConfig = serializeThinkingConfig(route.thinking);
105
122
  return thinkingConfig ? { thinkingConfig } : {};
106
123
  })(),
107
- } }, requestType: "agent", userAgent: "antigravity", requestId };
124
+ }, sessionId: envelope.sessionId, labels: envelope.labels }, requestType: "agent", userAgent: "antigravity", requestId: envelope.requestId };
108
125
  }
109
126
  catch (error) {
110
127
  if (error instanceof ContextSerializationError)
@@ -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;
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benjamolina/pi-antigravity-guard",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "description": "Pi adapter for Antigravity Guard",
5
5
  "type": "module",
6
6
  "license": "MIT",