@cortexkit/pi-antigravity-auth 3.0.1 → 3.0.3
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/convert.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/dist/convert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,OAAO,EAMR,MAAM,uBAAuB,CAAA;AAM9B,qCAAqC;AACrC,KAAK,UAAU,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,UAAU,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAClD;IACE,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,GACD;IACE,gBAAgB,EAAE;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;CACF,CAAA;AAEL,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AAED,UAAU,UAAU;IAClB,oBAAoB,EAAE,KAAK,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,iBAAiB,CAAC,EAAE;QAAE,KAAK,EAAE,UAAU,EAAE,CAAA;KAAE,CAAA;CAC5C;AAwED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,OAAO,EAMR,MAAM,uBAAuB,CAAA;AAM9B,qCAAqC;AACrC,KAAK,UAAU,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,UAAU,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAClD;IACE,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,GACD;IACE,gBAAgB,EAAE;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;CACF,CAAA;AAEL,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AAED,UAAU,UAAU;IAClB,oBAAoB,EAAE,KAAK,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,iBAAiB,CAAC,EAAE;QAAE,KAAK,EAAE,UAAU,EAAE,CAAA;KAAE,CAAA;CAC5C;AAwED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAqJD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,yBAAyB,GAClC,aAAa,CAiBf"}
|
package/dist/index.js
CHANGED
|
@@ -713,7 +713,7 @@ function convertMessages(messages, options) {
|
|
|
713
713
|
}
|
|
714
714
|
return contents;
|
|
715
715
|
}
|
|
716
|
-
function convertTools(tools) {
|
|
716
|
+
function convertTools(tools, model) {
|
|
717
717
|
if (!tools?.length) return void 0;
|
|
718
718
|
return [
|
|
719
719
|
{
|
|
@@ -723,7 +723,9 @@ function convertTools(tools) {
|
|
|
723
723
|
functionDeclarations: tools.map((tool) => ({
|
|
724
724
|
name: tool.name,
|
|
725
725
|
description: tool.description,
|
|
726
|
-
parameters: toGeminiSchema(tool.parameters
|
|
726
|
+
parameters: toGeminiSchema(tool.parameters, {
|
|
727
|
+
moveNumericConstraintsToDescription: model?.replace(/^antigravity-/, "").startsWith("gpt-oss-")
|
|
728
|
+
})
|
|
727
729
|
}))
|
|
728
730
|
}
|
|
729
731
|
];
|
|
@@ -750,7 +752,7 @@ function buildGeminiRequest(context, options) {
|
|
|
750
752
|
contents: convertMessages(context.messages, options)
|
|
751
753
|
};
|
|
752
754
|
const { systemPrompt, tools } = resolveInstructionState(context);
|
|
753
|
-
const geminiTools = convertTools(tools);
|
|
755
|
+
const geminiTools = convertTools(tools, options?.model);
|
|
754
756
|
if (geminiTools) request.tools = geminiTools;
|
|
755
757
|
if (systemPrompt.trim()) {
|
|
756
758
|
request.systemInstruction = {
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/commands.ts", "../src/vault-setup.ts", "../src/credential-cache.ts", "../src/paths.ts", "../src/stream.ts", "../src/convert.ts", "../src/vault-source.ts"],
|
|
4
|
-
"sourcesContent": ["import { join } from 'node:path'\nimport {\n ANTIGRAVITY_PROVIDER_ID,\n authorizeAntigravity,\n enrollmentAuthority,\n exchangeAntigravity,\n getPublicModelDefinitions,\n loadCommonAuthPiSlot,\n refreshAntigravityToken,\n} from '@cortexkit/antigravity-auth-core'\nimport type { PluginExtraSection } from '@cortexkit/antigravity-auth-core/common-auth/commands'\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n} from '@earendil-works/pi-ai'\nimport {\n type ExtensionAPI,\n getAgentDir,\n type ProviderConfig,\n readStoredCredential,\n} from '@earendil-works/pi-coding-agent'\n\nimport {\n createPiAntigravityAccountSections,\n type PiAntigravityAccountSections,\n registerPiAntigravityCommand,\n} from './commands.ts'\nimport { rememberPackedRefresh } from './credential-cache.ts'\nimport { getPiAntigravityVaultDir } from './paths.ts'\nimport {\n createCortexKitAntigravityVaultStream,\n streamCortexKitAntigravity,\n} from './stream.ts'\nimport {\n createPiVaultSection,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n type PiVaultModeRead,\n type PiVaultModeRecord,\n PiVaultSetupError,\n} from './vault-setup.ts'\nimport {\n createPiVaultAccountsPort,\n createPiVaultRuntime,\n createPiVaultSend,\n type PiVaultSeams,\n} from './vault-source.ts'\n\n/** Refresh value of the vault placeholder login; local mode must never refresh it. */\nexport const CUSTODY_PLACEHOLDER_REFRESH_PREFIX = 'claustrum-tombstone:v1:'\n\n/** Non-secret key that lets Pi list custody models without a login; never sent. */\nexport const CUSTODY_PROVIDER_KEY_MARKER = 'antigravity-vault-custody'\n\nfunction textImageInput(): Array<'text' | 'image'> {\n return ['text', 'image']\n}\n\nasync function loginAntigravity(\n callbacks: OAuthLoginCallbacks,\n): Promise<OAuthCredentials> {\n const auth = await authorizeAntigravity()\n callbacks.onAuth({ url: auth.url })\n const code = await callbacks.onPrompt({\n message: 'Paste the Antigravity OAuth callback URL or code:',\n })\n\n // The state (PKCE verifier + project) is carried in the authorize URL; reuse\n // it so the code exchange can recover the verifier.\n const authState = new URL(auth.url).searchParams.get('state') ?? ''\n\n // Accept either a raw code or a full redirect URL with ?code= and &state=.\n let rawCode = code.trim()\n let state = authState\n try {\n const url = new URL(rawCode)\n const codeParam = url.searchParams.get('code')\n const stateParam = url.searchParams.get('state')\n if (codeParam) rawCode = codeParam\n if (stateParam) state = stateParam\n } catch {\n // Not a URL \u2014 treat the input as a bare authorization code.\n }\n\n const result = await exchangeAntigravity(rawCode, state)\n if (result.type !== 'success') {\n throw new Error(`Antigravity OAuth exchange failed: ${result.error}`)\n }\n\n return {\n refresh: result.refresh,\n access: result.access,\n expires: result.expires,\n }\n}\n\nasync function refreshAntigravityCredentials(\n credentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n // Local mode refreshes Pi's own login only. The vault placeholder is not a\n // login: refreshing it would send it to Google as a refresh token.\n if (credentials.refresh.startsWith(CUSTODY_PLACEHOLDER_REFRESH_PREFIX))\n throw new Error(\n 'Pi holds the Antigravity vault placeholder, not a login. Run /login, or serve Antigravity from the vault.',\n )\n // Stored refresh is `refreshToken|projectId|managedProjectId`.\n const refreshToken = credentials.refresh.split('|')[0] ?? credentials.refresh\n const refreshed = await refreshAntigravityToken(refreshToken)\n // Preserve the project segments packed into the stored refresh string.\n const projectSegments = credentials.refresh.includes('|')\n ? credentials.refresh.slice(credentials.refresh.indexOf('|'))\n : ''\n return {\n refresh: `${refreshed.refresh}${projectSegments}`,\n access: refreshed.access,\n expires: refreshed.expires,\n }\n}\n\nfunction publicModels(): NonNullable<ProviderConfig['models']> {\n return (\n Object.values(getPublicModelDefinitions())\n // Pi's AssistantMessage protocol has no image-output content type. Keep\n // generation-only image routes out of the chat model catalog rather than\n // advertising output that the stream contract cannot represent.\n .filter((model) => !model.modalities.output.includes('image'))\n .map((model) => ({\n id: model.id,\n name: model.name,\n reasoning: model.reasoning,\n input: textImageInput(),\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n contextWindow: model.limit.context,\n maxTokens: model.limit.output,\n }))\n )\n}\n\nfunction localProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n assertLocalAdmission: () => Promise<void>,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit OAuth)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n oauth: {\n name: 'Google Antigravity (CortexKit)',\n login: async (callbacks) => {\n await assertLocalAdmission()\n return loginAntigravity(callbacks)\n },\n refreshToken: async (credentials) => {\n await assertLocalAdmission()\n return refreshAntigravityCredentials(credentials)\n },\n getApiKey: (credentials) => {\n // Bridge the packed refresh (refreshToken|projectId|managedProjectId)\n // to the stream, which otherwise only receives the bare access token.\n rememberPackedRefresh(credentials.access, credentials.refresh)\n return credentials.access\n },\n },\n streamSimple: (model, context, options) =>\n streamCortexKitAntigravity(model, context, options, assertLocalAdmission),\n }\n}\n\n/** Custody (or unreadable mode): no OAuth, so Pi never refreshes locally. */\nfunction custodyProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n send: ReturnType<typeof createPiVaultSend>,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit vault)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n apiKey: CUSTODY_PROVIDER_KEY_MARKER,\n streamSimple: createCortexKitAntigravityVaultStream(\n send,\n CUSTODY_PROVIDER_KEY_MARKER,\n ),\n }\n}\n\n/**\n * Registered while the native credential slot cannot be synchronized with the\n * chosen mode. It keeps the same provider id and models, so Pi neither falls\n * back to its built-in Google catalog nor lists a second provider. It has no\n * OAuth, so Pi never refreshes or rewrites the native login, and every request\n * fails with the reason before anything is sent.\n */\nfunction refusingProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n reason: string,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit, unavailable)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n apiKey: CUSTODY_PROVIDER_KEY_MARKER,\n streamSimple: createCortexKitAntigravityVaultStream(async () => {\n throw new PiVaultSetupError(\n `${reason} Resolve it from /antigravity; Antigravity requests are refused until then. No request was sent.`,\n )\n }, CUSTODY_PROVIDER_KEY_MARKER),\n }\n}\n\n/**\n * The vault runtime Pi composes custody from: the public `./claustrum` entry\n * of `@cortexkit/common-auth`, the setup-only enrollment connection, and the\n * shared Antigravity vault account source for the `pi` host.\n */\nexport interface PiAntigravityExtension {\n /**\n * The Vault section for the shared command menu, where enrollment, mode\n * switching and account choice happen.\n */\n readonly vaultSection: PluginExtraSection\n /** Pi's own Accounts, Quota, Routing and Limits sections for the same menu. */\n readonly accountSections: PiAntigravityAccountSections\n}\n\n/**\n * Register the Antigravity provider for the mode the user chose: Pi's own\n * login (local, the default) or the vault (custody). Changing the mode in\n * the Vault section re-registers the same provider id, so Pi never lists two.\n * `seams` replaces only I/O (vault client transport, file paths, auth slot)\n * for tests; Pi's default entry passes none.\n */\nexport async function registerCortexKitPiAntigravity(\n pi: Pick<ExtensionAPI, 'registerProvider' | 'registerCommand'> &\n Partial<Pick<ExtensionAPI, 'on'>>,\n seams: PiVaultSeams = {},\n): Promise<PiAntigravityExtension> {\n const models = publicModels()\n const readHostSlot =\n seams.readHostSlot ?? (() => readStoredCredential(ANTIGRAVITY_PROVIDER_ID))\n let refreshRegistry: (() => void) | undefined\n const vault = createPiVaultRuntime(readHostSlot, seams, async () => {\n try {\n await synchronizeSlot()\n } finally {\n refreshRegistry?.()\n }\n })\n const send = createPiVaultSend(vault.requestPath)\n\n const register = (mode: PiVaultModeRead) => {\n const local = mode.ok && mode.record.mode === 'local'\n pi.registerProvider(\n ANTIGRAVITY_PROVIDER_ID,\n local\n ? localProviderConfig(models, assertLocalAdmission)\n : custodyProviderConfig(models, send),\n )\n }\n const currentMode = async (): Promise<PiVaultModeRecord> => {\n const setup = await vault.setup()\n const status = await setup.sourceStatus()\n const authority = await enrollmentAuthority(\n setup.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (authority === 'unreadable' || status.mode === 'unreadable') {\n throw new PiVaultSetupError(\n 'Vault enrollment or source settings cannot be read. Local credentials remain unavailable.',\n )\n }\n if (authority === 'vault')\n return {\n version: 1,\n mode: 'custody',\n ...(status.selectedRouteId ? { routeId: status.selectedRouteId } : {}),\n }\n if (status.mode !== 'local')\n throw new PiVaultSetupError(\n 'Vault enrollment must be approved before activating vault credentials.',\n )\n return { version: 1, mode: 'local' }\n }\n const assertLocalAdmission = async () => {\n if ((await currentMode()).mode !== 'local')\n throw new PiVaultSetupError(\n 'Vault enrollment excludes local login, refresh and request execution.',\n )\n }\n const synchronizeSlotOnce = async () => {\n try {\n await swapSlotForMode()\n } catch (error) {\n // Leave the provider registered but refusing, so a failed swap neither\n // serves from the wrong credential nor unregisters the models.\n pi.registerProvider(\n ANTIGRAVITY_PROVIDER_ID,\n refusingProviderConfig(\n models,\n error instanceof Error ? error.message : String(error),\n ),\n )\n throw error\n }\n }\n // Startup, session_start and every mode change synchronize the slot. Run them\n // one at a time: each reads the mode when it starts, so the run that\n // registers last is the one that read the newest mode.\n let synchronizing: Promise<void> = Promise.resolve()\n const synchronizeSlot = (): Promise<void> => {\n const run = synchronizing.then(synchronizeSlotOnce)\n synchronizing = run.catch(() => {})\n return run\n }\n const swapSlotForMode = async () => {\n const mode = await currentMode()\n const { openPiSlot } = await (seams.loadPiSlot ?? loadCommonAuthPiSlot)()\n const slot = openPiSlot({\n authPath: seams.nativeAuthPath ?? join(getAgentDir(), 'auth.json'),\n stashPath:\n seams.nativeStashPath ??\n join(\n seams.vaultDir ?? getPiAntigravityVaultDir(),\n 'google-login-stash.json',\n ),\n provider: ANTIGRAVITY_PROVIDER_ID,\n placeholderKey: CUSTODY_PROVIDER_KEY_MARKER,\n })\n if (mode.mode === 'custody') await slot.enterVault()\n else if ((await slot.exitVault()) === 'conflict')\n throw new PiVaultSetupError(\n 'The native Google login changed. It was not overwritten; restore the saved login after resolving the conflict.',\n )\n const after = await currentMode()\n if (after.mode !== mode.mode)\n throw new PiVaultSetupError(\n 'Vault enrollment changed while the credential slot was being synchronized. The account source was not activated.',\n )\n register({ ok: true, record: after })\n }\n // Pi's first catalog refresh reads auth.json to decide which models are usable.\n // Install the vault marker before the factory returns so discovery and the\n // first request cannot refresh the dormant Google login. A failed swap has\n // registered the refusing provider; the factory still resolves so the\n // /antigravity menu below, which holds the remedies, stays registered.\n await synchronizeSlot().catch(() => {})\n pi.on?.('session_start', async (_event, context) => {\n refreshRegistry = () => context.modelRegistry.refresh()\n try {\n await synchronizeSlot()\n } finally {\n refreshRegistry()\n }\n })\n\n const accounts = createPiVaultAccountsPort(vault.requestPath)\n const extension: PiAntigravityExtension = {\n accountSections: createPiAntigravityAccountSections({\n setup: vault.setup,\n accounts: () => accounts,\n }),\n vaultSection: createPiVaultSection({\n setup: vault.setup,\n accounts: () => accounts,\n }),\n }\n registerPiAntigravityCommand(pi, {\n sections: extension.accountSections,\n extras: [extension.vaultSection],\n ...(seams.loadCommands && { loadCommands: seams.loadCommands }),\n })\n return extension\n}\n\nexport default async function cortexKitPiAntigravityAuth(\n pi: ExtensionAPI,\n): Promise<void> {\n await registerCortexKitPiAntigravity(pi)\n}\n", "/**\n * Pi's `/antigravity` command: the core's shared Antigravity menu in its\n * host-sections mode, drawn with Pi's extension UI by the library's Pi\n * renderer. Pi has one account at a time and no account rows, so it supplies\n * all four account slots itself. The commands library loads on the first\n * invocation, and every invocation builds a fresh menu.\n */\n\nimport {\n ANTIGRAVITY_MENU_COMMAND,\n type AntigravityMenuSections,\n type CommonAuthCommandsModule,\n createAntigravityCommandMenu,\n loadCommonAuthCommands,\n} from '@cortexkit/antigravity-auth-core'\nimport type {\n ItemDefinition,\n PluginExtraSection,\n} from '@cortexkit/antigravity-auth-core/common-auth/commands'\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent'\n\nimport {\n opaqueItemId,\n type PiVaultAccountChoice,\n type PiVaultAccountsPort,\n type PiVaultSetup,\n type PiVaultSetupStatus,\n vaultAccountName,\n} from './vault-setup.ts'\n\nexport interface PiAntigravityCommandOptions {\n sections: AntigravityMenuSections\n extras: readonly PluginExtraSection[]\n /** Loads the commands library; defaults to the core's lazy loader. */\n loadCommands?: () => Promise<CommonAuthCommandsModule>\n}\n\nexport function registerPiAntigravityCommand(\n pi: Pick<ExtensionAPI, 'registerCommand'>,\n options: PiAntigravityCommandOptions,\n): void {\n const loadCommands = options.loadCommands ?? loadCommonAuthCommands\n pi.registerCommand(ANTIGRAVITY_MENU_COMMAND, {\n description:\n 'Google Antigravity: the account Pi serves, and the Claustrum vault',\n handler: async (_args, ctx) => {\n const commands = await loadCommands()\n const menu = createAntigravityCommandMenu({\n commands,\n source: 'sections',\n sections: options.sections,\n extras: options.extras,\n })\n await commands.runPiCommandMenu(menu, ctx.ui, {\n sessionId: ctx.sessionManager.getSessionId(),\n })\n },\n })\n}\n\n// ---------------------------------------------------------------------------\n// Pi's own Accounts, Quota, Routing and Limits sections\n// ---------------------------------------------------------------------------\n\n/**\n * The menu's four account slots, built from what Pi actually has: one\n * account at a time (its own login, or one vault account), no pool, no\n * rotation and no recorded quota. Nothing here pretends to be a pool row.\n */\nexport type PiAntigravityAccountSections = AntigravityMenuSections\n\nexport interface PiAntigravityAccountSectionsOptions {\n setup: () => Promise<PiVaultSetup>\n accounts: () => PiVaultAccountsPort\n}\n\n/** The vault account Pi sends with now, when custody can name one. */\nfunction servingAccount(\n status: PiVaultSetupStatus,\n accounts: readonly PiVaultAccountChoice[],\n): PiVaultAccountChoice | undefined {\n const available = accounts.filter((account) => !account.declined)\n if (status.selectedRouteId !== undefined)\n return available.find(\n (account) => account.routeId === status.selectedRouteId,\n )\n return available.length === 1 ? available[0] : undefined\n}\n\nasync function custodyAccounts(\n status: PiVaultSetupStatus,\n options: PiAntigravityAccountSectionsOptions,\n): Promise<{ list: readonly PiVaultAccountChoice[]; problem?: string }> {\n if (status.mode !== 'custody' || status.enrollment.state !== 'approved')\n return { list: [] }\n try {\n return { list: await options.accounts().list() }\n } catch (error) {\n return {\n list: [],\n problem: `Vault accounts unavailable: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n}\n\nfunction localLoginLine(status: PiVaultSetupStatus): string {\n switch (status.hostSlot) {\n case 'dormant':\n return 'The native Pi login is dormant while vault enrollment controls serving.'\n case 'login':\n return \"Signed in with Pi's own login. Pi's /login replaces it and /logout removes it.\"\n case 'placeholder':\n return 'Pi holds the vault placeholder, not a login. Run /login, or serve from the vault in the Vault section.'\n case 'empty':\n return \"Not signed in. Run Pi's /login to sign in.\"\n }\n}\n\nexport function createPiAntigravityAccountSections(\n options: PiAntigravityAccountSectionsOptions,\n): PiAntigravityAccountSections {\n return {\n accounts: {\n title: 'Accounts',\n build: async () => {\n const status = await (await options.setup()).status()\n if (status.mode === 'unreadable')\n return {\n lines: [\n `The vault mode file is unreadable (${status.modeProblem ?? 'unknown problem'}); Pi serves nothing until a mode is chosen in the Vault section.`,\n ],\n }\n if (status.mode === 'local')\n return {\n lines: [\n \"Pi serves Antigravity from its own login, one account, kept in Pi's auth store.\",\n localLoginLine(status),\n ],\n }\n const { list, problem } = await custodyAccounts(status, options)\n const serving = servingAccount(status, list)\n const items: ItemDefinition[] = list.map((account) => ({\n id: opaqueItemId(account.routeId),\n label: vaultAccountName(list, account),\n detail: account.declined\n ? 'declined on this host'\n : account === serving\n ? 'serving Pi'\n : 'available',\n }))\n return {\n lines: [\n 'Pi serves Antigravity from the vault, one account at a time. Choose, decline or accept accounts in the Vault section.',\n ...(status.hostSlot === 'login'\n ? [\n 'Conflict: Pi also holds its own login. Requests are refused until /logout or a switch back to the local login.',\n ]\n : []),\n ...(problem ? [problem] : []),\n ],\n items,\n }\n },\n },\n quota: {\n title: 'Quota',\n build: () => ({\n lines: [\n \"Pi does not record Antigravity quota. A request Google refuses for quota fails with Google's own error.\",\n ],\n }),\n },\n routing: {\n title: 'Routing',\n build: async () => {\n const status = await (await options.setup()).status()\n if (status.mode === 'unreadable')\n return {\n lines: [\n 'Vault enrollment authority is unreadable; requests are refused. Recover or Disconnect in the Vault section.',\n ],\n }\n if (status.mode !== 'custody')\n return {\n lines: [\n \"Every request uses Pi's own login. There is no account rotation.\",\n ],\n }\n const { list } = await custodyAccounts(status, options)\n const serving = servingAccount(status, list)\n return {\n lines: [\n serving\n ? `Every request uses ${vaultAccountName(list, serving)}, with a fresh token and project from the vault for each send. There is no account rotation.`\n : 'No single vault account is chosen, so requests are refused. Choose one in the Vault section. There is no account rotation.',\n ],\n }\n },\n },\n limits: {\n title: 'Limits',\n build: () => ({\n lines: [\n 'Pi has no per-account limits for Antigravity: with one account there is nothing to fall back to.',\n ],\n }),\n },\n }\n}\n", "/**\n * Setup for serving Pi's Antigravity provider from the Claustrum vault\n * (\"custody\") instead of Pi's own login (\"local\"). The two never serve\n * together. Enrollment as `antigravity-auth-pi` runs only from the Vault\n * menu section, never from a model request; the enrollment token stays in\n * the vault library's owner-only file and Pi's auth slot is only read.\n */\n\nimport { createHash, randomBytes } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport type { CommonAuthClaustrumModule } from '@cortexkit/antigravity-auth-core'\nimport {\n ANTIGRAVITY_PROVIDER_ID,\n enrollmentAuthority,\n} from '@cortexkit/antigravity-auth-core'\nimport { writeJsonAtomic } from '@cortexkit/antigravity-auth-core/atomic-write'\nimport type {\n ClaustrumEnrollmentConnection,\n ClaustrumEnrollmentPaths,\n ClaustrumEnrollmentStatus,\n HostSlotContent,\n} from '@cortexkit/antigravity-auth-core/common-auth/claustrum'\nimport type {\n ActionDefinition,\n ActionOutcome,\n ItemDefinition,\n PluginExtraSection,\n} from '@cortexkit/antigravity-auth-core/common-auth/commands'\n\n/** Pi's provider id; also the key of its auth slot in Pi's auth.json. */\nexport const PI_ANTIGRAVITY_PROVIDER_ID = ANTIGRAVITY_PROVIDER_ID\n/** The host name this extension enrolls under, one enrollment per host. */\nexport const PI_ANTIGRAVITY_VAULT_HOST = 'pi'\n/** The enrollment name the operator sees and approves for Pi. */\nexport const PI_ANTIGRAVITY_ENROLLMENT_NAME = 'antigravity-auth-pi'\n\n// ---------------------------------------------------------------------------\n// Mode file\n// ---------------------------------------------------------------------------\n\nexport type PiAntigravityMode = 'local' | 'custody'\n\n/**\n * What Pi serves Antigravity from. `routeId` names the vault account the\n * user picked; it is a roster route id, never credential material.\n */\nexport interface PiVaultModeRecord {\n readonly version: 1\n readonly mode: PiAntigravityMode\n readonly routeId?: string\n}\n\nexport type PiVaultModeRead =\n | { readonly ok: true; readonly record: PiVaultModeRecord }\n | { readonly ok: false; readonly reason: string }\n\nconst LOCAL_MODE: PiVaultModeRecord = Object.freeze({\n version: 1,\n mode: 'local',\n})\n\nfunction parseModeRecord(raw: unknown): PiVaultModeRecord | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw))\n return undefined\n const record = raw as Record<string, unknown>\n for (const key of Object.keys(record))\n if (key !== 'version' && key !== 'mode' && key !== 'routeId')\n return undefined\n if (record.version !== 1) return undefined\n if (record.mode !== 'local' && record.mode !== 'custody') return undefined\n if (record.routeId === undefined)\n return Object.freeze({ version: 1, mode: record.mode })\n if (typeof record.routeId !== 'string' || record.routeId.trim() === '')\n return undefined\n return Object.freeze({\n version: 1,\n mode: record.mode,\n routeId: record.routeId,\n })\n}\n\n/**\n * Read the mode file. A missing file is local mode, so an extension that\n * was never set up keeps serving its single login. A file that exists but\n * cannot be understood is reported, not guessed: the caller refuses to serve\n * rather than pick a mode the user may not have chosen.\n */\nexport function readPiVaultMode(path: string): PiVaultModeRead {\n let text: string\n try {\n text = readFileSync(path, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException | null)?.code === 'ENOENT')\n return { ok: true, record: LOCAL_MODE }\n return { ok: false, reason: 'the vault mode file could not be read' }\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n return { ok: false, reason: 'the vault mode file is not valid JSON' }\n }\n const record = parseModeRecord(raw)\n return record\n ? { ok: true, record }\n : { ok: false, reason: 'the vault mode file has an unknown shape' }\n}\n\nexport async function writePiVaultMode(\n path: string,\n record: PiVaultModeRecord,\n): Promise<void> {\n const value: PiVaultModeRecord =\n record.routeId === undefined\n ? { version: 1, mode: record.mode }\n : { version: 1, mode: record.mode, routeId: record.routeId }\n await writeJsonAtomic(path, value)\n}\n\n// ---------------------------------------------------------------------------\n// Vault accounts as setup sees them\n// ---------------------------------------------------------------------------\n\n/** An account shown in the vault menu; declined accounts are excluded from request selection. */\nexport interface PiVaultAccountChoice {\n readonly routeId: string\n /** Display label from the vault roster; may hold the account's email. */\n readonly label: string\n readonly email?: string\n readonly declined: boolean\n}\n\n/**\n * Vault account discovery and selection used by the setup menu.\n * These operations become available after the operator approves access.\n */\nexport interface PiVaultAccountsPort {\n /** Reload and save the list of permitted vault accounts, then return it to the menu. */\n list(): Promise<readonly PiVaultAccountChoice[]>\n decline(routeId: string): Promise<void>\n accept(routeId: string): Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// Setup controller\n// ---------------------------------------------------------------------------\n\nexport interface PiVaultSetupStatus {\n readonly mode: PiAntigravityMode | 'unreadable'\n readonly modeProblem?: string\n readonly selectedRouteId?: string\n readonly enrollment: ClaustrumEnrollmentStatus\n readonly hostSlot: HostSlotContent | 'dormant'\n}\n\nexport interface PiVaultSetupOptions {\n claustrum: CommonAuthClaustrumModule\n /** Pi's vault directory (see `getPiAntigravityVaultDir`). */\n stateDir: string\n /** Pi's vault mode file (see `getPiAntigravityVaultModeFile`). */\n modeFile: string\n /** Read Pi's own Google credential record, only when local accounts are selected. */\n readHostSlot: () => unknown\n /** Opens the setup-only enrollment connection to the vault. */\n connectEnrollment: () => Promise<ClaustrumEnrollmentConnection>\n /** Re-register the Google provider after its selected account source changes. */\n onModeChanged?: (record: PiVaultModeRecord) => void | Promise<void>\n now?: () => number\n}\n\n/** A setup action refused before anything changed, with a message for the user. */\nexport class PiVaultSetupError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PiVaultSetupError'\n }\n}\n\nexport class PiVaultSetup {\n readonly #options: PiVaultSetupOptions\n readonly paths: ClaustrumEnrollmentPaths\n\n constructor(options: PiVaultSetupOptions) {\n this.#options = options\n this.paths = options.claustrum.hostEnrollmentPaths({\n stateDir: options.stateDir,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n })\n }\n\n #hostSlot(): HostSlotContent {\n return this.#options.claustrum.classifyHostSlot(\n this.#options.readHostSlot(),\n PI_ANTIGRAVITY_PROVIDER_ID,\n )\n }\n\n /** Read vault approval and local/vault settings without opening Pi's Google credentials. */\n async sourceStatus(): Promise<Omit<PiVaultSetupStatus, 'hostSlot'>> {\n const mode = readPiVaultMode(this.#options.modeFile)\n const enrollment = await this.#options.claustrum\n .readClaustrumEnrollmentStatus(this.paths, PI_ANTIGRAVITY_ENROLLMENT_NAME)\n .catch(\n (): ClaustrumEnrollmentStatus => ({\n state: 'blocked',\n proposedName: PI_ANTIGRAVITY_ENROLLMENT_NAME,\n code: 'unreadable-state',\n }),\n )\n const authority = await enrollmentAuthority(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n this.#options.claustrum,\n )\n return {\n ...(authority !== 'local'\n ? {\n mode:\n authority === 'vault'\n ? ('custody' as const)\n : ('unreadable' as const),\n ...(mode.ok &&\n mode.record.routeId !== undefined && {\n selectedRouteId: mode.record.routeId,\n }),\n }\n : mode.ok\n ? {\n mode: mode.record.mode,\n ...(mode.record.routeId !== undefined && {\n selectedRouteId: mode.record.routeId,\n }),\n }\n : { mode: 'unreadable' as const, modeProblem: mode.reason }),\n enrollment,\n }\n }\n\n /** Inspect the native login only when local accounts are selected. */\n async status(): Promise<PiVaultSetupStatus> {\n const source = await this.sourceStatus()\n return {\n ...source,\n hostSlot: source.mode === 'local' ? this.#hostSlot() : 'dormant',\n }\n }\n\n /**\n * Propose Pi to the vault or poll its recorded proposal. Clear a denied or\n * blocked request before starting again. Only setup actions call this method.\n */\n async connectStep(): Promise<ClaustrumEnrollmentStatus> {\n const client = await this.#options.connectEnrollment()\n try {\n const manager = new this.#options.claustrum.ClaustrumEnrollmentManager({\n client,\n paths: this.paths,\n proposedName: PI_ANTIGRAVITY_ENROLLMENT_NAME,\n ...(this.#options.now && { now: this.#options.now }),\n })\n const current = await manager.status()\n if (current.state === 'denied' || current.state === 'blocked')\n await manager.resetTerminal()\n const reconciled = await manager.reconcile()\n if (reconciled.state === 'approved') {\n const saved = readPiVaultMode(this.#options.modeFile)\n await this.useVault(\n saved.ok && saved.record.mode === 'custody'\n ? saved.record.routeId\n : undefined,\n )\n }\n return reconciled\n } finally {\n client.close()\n }\n }\n\n /**\n * Select the vault account used for requests after the operator approves\n * enrollment. Await the host's Google credential-slot transition before\n * returning, so provider registration cannot race it.\n */\n async useVault(routeId?: string): Promise<PiVaultModeRecord> {\n const enrollment =\n await this.#options.claustrum.readClaustrumEnrollmentStatus(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (enrollment.state !== 'approved')\n throw new PiVaultSetupError(\n 'Pi is not enrolled with the vault yet. Request access and wait for the operator to approve it first.',\n )\n if (routeId !== undefined && routeId.trim() === '')\n throw new PiVaultSetupError('Choose a vault account to use.')\n const record: PiVaultModeRecord =\n routeId === undefined\n ? { version: 1, mode: 'custody' }\n : { version: 1, mode: 'custody', routeId }\n await writePiVaultMode(this.#options.modeFile, record)\n await this.#options.onModeChanged?.(record)\n return record\n }\n\n /** Use Pi's local login only after vault enrollment has been disconnected. */\n async useLocal(): Promise<PiVaultModeRecord> {\n if (\n (await enrollmentAuthority(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n this.#options.claustrum,\n )) !== 'local'\n ) {\n throw new PiVaultSetupError(\n 'Disconnect vault enrollment before using local accounts.',\n )\n }\n await writePiVaultMode(this.#options.modeFile, LOCAL_MODE)\n await this.#options.onModeChanged?.(LOCAL_MODE)\n return LOCAL_MODE\n }\n\n /**\n * Forget this host's enrollment (token and ceremony state) and go back to\n * local mode. The vault keeps the enrollment approved until the operator\n * revokes it there.\n */\n async disconnect(): Promise<void> {\n const result = await this.#options.claustrum.disconnectClaustrumEnrollment(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (result === 'busy')\n throw new PiVaultSetupError(\n 'Vault enrollment is busy; disconnect did not change it.',\n )\n await writePiVaultMode(this.#options.modeFile, LOCAL_MODE)\n await this.#options.onModeChanged?.(LOCAL_MODE)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Rendering through Pi's command and dialog surfaces\n// ---------------------------------------------------------------------------\n\nfunction describeEnrollment(status: ClaustrumEnrollmentStatus): string {\n switch (status.state) {\n case 'idle':\n return 'not requested'\n case 'pending':\n return status.retryCode\n ? `waiting for operator approval (retrying: ${status.retryCode})`\n : 'waiting for operator approval'\n case 'approved':\n return `approved as ${status.approvedName ?? status.proposedName}`\n case 'denied':\n return 'denied by the operator'\n case 'blocked':\n return `blocked (${status.code})`\n case 'unavailable':\n return `vault unavailable (${status.code})`\n case 'busy':\n return 'another setup step is running'\n }\n}\n\nfunction describeHostSlot(slot: HostSlotContent): string {\n switch (slot) {\n case 'login':\n return 'signed in with a Pi login'\n case 'placeholder':\n return 'holds the vault placeholder'\n case 'empty':\n return 'empty'\n }\n}\n\n/** Setup-menu status text with no credentials or Antigravity project identifiers. */\nexport function formatPiVaultSetupStatus(status: PiVaultSetupStatus): string[] {\n const lines = [\n `Mode: ${\n status.mode === 'custody'\n ? 'vault (custody)'\n : status.mode === 'local'\n ? 'local Pi login'\n : `unreadable (${status.modeProblem ?? 'unknown problem'})`\n }`,\n `Enrollment (${PI_ANTIGRAVITY_ENROLLMENT_NAME}): ${describeEnrollment(status.enrollment)}`,\n status.hostSlot === 'dormant'\n ? 'Pi auth slot: dormant (not read)'\n : `Pi auth slot: ${describeHostSlot(status.hostSlot)}`,\n ]\n if (status.selectedRouteId !== undefined)\n lines.push('Vault account: a specific account is chosen (marked below)')\n if (status.mode === 'local' && status.hostSlot === 'placeholder')\n lines.push(\n 'Conflict: local mode has no login to serve. Run /login or switch to the vault.',\n )\n return lines\n}\n\n// ---------------------------------------------------------------------------\n// Vault section of the shared command menu\n// ---------------------------------------------------------------------------\n\nexport interface PiVaultSectionOptions {\n /** The setup controller; created on first use so the vault library loads lazily. */\n setup: () => Promise<PiVaultSetup>\n /** Vault account actions, available only after the approved account source is constructed. */\n accounts?: () => PiVaultAccountsPort | undefined\n /** How Request access polls for the operator's approval (tests shorten it). */\n wait?: PiVaultWaitOptions\n}\n\nexport interface PiVaultWaitOptions {\n pollIntervalMs?: number\n timeoutMs?: number\n sleep?: (ms: number) => Promise<void>\n}\n\n/**\n * Menu payloads leave this process (the shared menu may hand them to a\n * renderer), so a vault account's item id is an opaque digest of its route\n * id under a per-process salt: stable while Pi runs, so an apply finds the\n * same account the user saw, but never the raw route id.\n */\nconst ITEM_ID_SALT = randomBytes(16)\n\n/**\n * A vault account's display name in the menu: its position in the vault's\n * list. The roster label is usually the account's email, which must not\n * leave this process in a menu payload; positions are shown, never accepted\n * as targets.\n */\nexport function vaultAccountName(\n listed: readonly PiVaultAccountChoice[],\n account: PiVaultAccountChoice,\n): string {\n return `Vault account ${listed.indexOf(account) + 1}`\n}\n\nexport function opaqueItemId(routeId: string): string {\n return `vault-${createHash('sha256').update(ITEM_ID_SALT).update(routeId).digest('hex').slice(0, 16)}`\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction refused(error: unknown): ActionOutcome {\n if (error instanceof PiVaultSetupError)\n return { ok: false, text: error.message, code: 'vault-refused' }\n throw error\n}\n\n/** Poll the enrollment until it leaves `pending`/`busy` or the wait ends. */\nasync function waitForApproval(\n setup: PiVaultSetup,\n wait: PiVaultWaitOptions = {},\n): Promise<ClaustrumEnrollmentStatus> {\n const sleep =\n wait.sleep ??\n ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)))\n const interval = wait.pollIntervalMs ?? 2_000\n const deadline = Date.now() + (wait.timeoutMs ?? 10 * 60_000)\n let status = await setup.connectStep()\n while (status.state === 'pending' || status.state === 'busy') {\n if (Date.now() >= deadline) return status\n await sleep(interval)\n status = await setup.connectStep()\n }\n return status\n}\n\n/**\n * The Vault section of Pi's command menu: mode and enrollment status, the\n * vault accounts with use/decline/accept, requesting access (the only place\n * enrollment runs), switching between the vault and the local Pi login, and\n * forgetting the enrollment. Shows status only, never the enrollment token,\n * and never a raw route id, roster label or email.\n */\nexport function createPiVaultSection(\n options: PiVaultSectionOptions,\n): PluginExtraSection {\n return {\n id: 'vault',\n title: 'Vault',\n build: async () => {\n const setup = await options.setup()\n const status = await setup.status()\n const approved = status.enrollment.state === 'approved'\n const lines = formatPiVaultSetupStatus(status)\n const items: ItemDefinition[] = []\n const port = approved ? options.accounts?.() : undefined\n if (port) {\n try {\n const listed = await port.list()\n for (const account of listed) {\n const name = vaultAccountName(listed, account)\n const serving =\n status.mode === 'custody' &&\n status.selectedRouteId === account.routeId\n items.push({\n id: opaqueItemId(account.routeId),\n label: name,\n detail: account.declined\n ? 'declined on this host'\n : serving\n ? 'serving Pi'\n : 'available',\n actions: account.declined\n ? [\n {\n id: 'accept',\n label: 'Accept on this host',\n run: async () => {\n await port.accept(account.routeId)\n return `${name} is accepted on this host.`\n },\n },\n ]\n : [\n {\n id: 'use',\n label: 'Serve Pi from this account',\n run: async () => {\n try {\n await setup.useVault(account.routeId)\n } catch (error) {\n return refused(error)\n }\n return `Pi now serves Antigravity from ${name}.`\n },\n },\n {\n id: 'decline',\n label: 'Decline on this host',\n description:\n 'It stays in the vault and in this list, and is never sent from this host until accepted again.',\n run: async () => {\n await port.decline(account.routeId)\n return `${name} is declined on this host.`\n },\n },\n ],\n })\n }\n } catch (error) {\n lines.push(`Vault accounts unavailable: ${errorText(error)}`)\n }\n }\n\n const actions: ActionDefinition[] = []\n if (!approved)\n actions.push({\n id: 'request-access',\n label: 'Request vault access',\n description: `Asks the vault to enroll Pi as ${PI_ANTIGRAVITY_ENROLLMENT_NAME}; the operator approves it in the vault.`,\n run: async ({ invocation }) => {\n const step = await setup.connectStep()\n if (step.state !== 'pending' && step.state !== 'busy')\n return {\n ok: step.state === 'approved',\n text: `Enrollment: ${describeEnrollment(step)}`,\n }\n // The approval happens outside Pi; keep polling and report to\n // the session that asked.\n void waitForApproval(setup, options.wait)\n .then((final) => {\n invocation.notify(\n `Enrollment: ${describeEnrollment(final)}`,\n final.state === 'approved' ? 'info' : 'warning',\n )\n })\n .catch((error: unknown) => {\n invocation.notify(\n `Requesting vault access failed: ${errorText(error)}`,\n 'error',\n )\n })\n return {\n ok: true,\n text: `Enrollment: ${describeEnrollment(step)}. You are told here when the operator decides.`,\n }\n },\n })\n if (approved && status.mode !== 'custody')\n actions.push({\n id: 'use-vault',\n label: 'Serve Pi from the vault',\n run: async () => {\n try {\n await setup.useVault(status.selectedRouteId)\n } catch (error) {\n return refused(error)\n }\n return 'Pi now serves Antigravity from the vault.'\n },\n })\n if (\n status.mode !== 'local' &&\n (status.enrollment.state === 'idle' ||\n status.enrollment.state === 'pending' ||\n status.enrollment.state === 'denied')\n )\n actions.push({\n id: 'use-local',\n label: 'Serve Pi from its own login',\n run: async () => {\n await setup.useLocal()\n return 'Pi now serves Antigravity from its own login. Run /login if it has none.'\n },\n })\n if (status.enrollment.state !== 'idle')\n actions.push({\n id: 'forget',\n label: 'Forget vault enrollment',\n description:\n \"Deletes Pi's enrollment token and returns to the local login. The operator can still revoke the enrollment in the vault.\",\n irreversible: true,\n confirm: `Forget the ${PI_ANTIGRAVITY_ENROLLMENT_NAME} enrollment? Using the vault again needs a new approval.`,\n run: async () => {\n await setup.disconnect()\n return 'Vault enrollment forgotten; Pi serves Antigravity from its own login.'\n },\n })\n\n return { lines, items, actions }\n },\n }\n}\n", "/**\n * In-process bridge for the packed refresh string.\n *\n * pi's provider framework extracts the bearer token via `oauth.getApiKey` and\n * passes only that access token to `streamSimple` (as `options.apiKey`). The\n * packed refresh (`refreshToken|projectId|managedProjectId`) that login/refresh\n * resolved is therefore not visible to the stream. We cache it here, keyed by\n * the access token, so the stream can recover the managed-project context and\n * avoid a redundant loadCodeAssist round-trip on every turn.\n */\n\nconst packedRefreshByAccessToken = new Map<string, string>()\n// Single-account extension: keep the map tiny.\nconst MAX_ENTRIES = 4\n\nexport function rememberPackedRefresh(\n accessToken: string,\n packedRefresh: string,\n): void {\n if (!accessToken) return\n if (packedRefreshByAccessToken.has(accessToken)) {\n packedRefreshByAccessToken.delete(accessToken)\n } else if (packedRefreshByAccessToken.size >= MAX_ENTRIES) {\n const oldest = packedRefreshByAccessToken.keys().next().value\n if (oldest !== undefined) packedRefreshByAccessToken.delete(oldest)\n }\n packedRefreshByAccessToken.set(accessToken, packedRefresh)\n}\n\nexport function getPackedRefresh(accessToken: string): string | undefined {\n return packedRefreshByAccessToken.get(accessToken)\n}\n", "import { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nexport function getPiConfigDir(): string {\n return process.env.PI_AGENT_DIR?.trim() || join(homedir(), '.pi', 'agent')\n}\n\nexport function getPiAntigravityAuthFile(): string {\n return (\n process.env.PI_ANTIGRAVITY_AUTH_FILE?.trim() ||\n join(getPiConfigDir(), 'antigravity-accounts.json')\n )\n}\n\n/**\n * Directory for Pi's Claustrum vault files (enrollment token and ceremony\n * state, the vault roster, the custody mode file). It sits next to the\n * account file in its own subdirectory so common-auth can restrict\n * its permissions without changing Pi's configuration directory.\n */\nexport function getPiAntigravityVaultDir(): string {\n return join(dirname(getPiAntigravityAuthFile()), 'antigravity-auth-vault')\n}\n\n/** Non-secret settings file selecting local or vault credentials for Pi requests. */\nexport function getPiAntigravityVaultModeFile(): string {\n return join(getPiAntigravityVaultDir(), 'pi-mode.json')\n}\n\n/** List of vault accounts Pi may use; contains account references, never tokens. */\nexport function getPiAntigravityVaultRosterFile(): string {\n return join(getPiAntigravityVaultDir(), 'pi-roster.json')\n}\n", "import {\n type AgyRequestScope,\n AgyRequestSessionStore,\n ANTIGRAVITY_ENDPOINT,\n applyAgyNativeGenerationConfig,\n buildAgyAgentRequestMetadata,\n buildAntigravityHarnessUserAgent,\n ensureProjectContext,\n fetchWithAgyCliTransport,\n forwardAbort,\n isRetiredAgyModel,\n orderAgyRequestPayloadInPlace,\n RETIRED_AGY_MODEL_MESSAGE,\n redactCredentialError,\n redactCredentialText,\n resolveModelForHeaderStyle,\n} from '@cortexkit/antigravity-auth-core'\nimport {\n type Api,\n type AssistantMessage,\n type AssistantMessageEventStream,\n type Context,\n calculateCost,\n createAssistantMessageEventStream,\n type JsonObject,\n type Model,\n type SimpleStreamOptions,\n type StopReason,\n type TextContent,\n type ThinkingContent,\n type ThinkingLevel,\n type ToolCall,\n} from '@earendil-works/pi-ai'\n\nimport { buildGeminiRequest } from './convert.ts'\nimport { getPackedRefresh } from './credential-cache.ts'\n\nconst STREAM_ACTION = 'streamGenerateContent'\nconst FALLBACK_SESSION_KEY = '__default__'\nconst TRAILING_USAGE_TIMEOUT_MS = 1_000\nconst requestSessions = new AgyRequestSessionStore('')\n\nasync function nextWithTimeout<T>(\n iterator: AsyncIterator<T>,\n timeoutMs: number,\n onTimeout: () => void,\n): Promise<IteratorResult<T> | undefined> {\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n iterator.next(),\n new Promise<undefined>((resolve) => {\n timer = setTimeout(() => {\n onTimeout()\n resolve(undefined)\n }, timeoutMs)\n }),\n ])\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\nfunction mapFinishReason(reason: string | null | undefined): StopReason {\n switch (reason) {\n case 'STOP':\n return 'stop'\n case 'MAX_TOKENS':\n return 'length'\n default:\n return reason ? 'stop' : 'stop'\n }\n}\n\nfunction createOutput(model: Model<Api>): AssistantMessage {\n return {\n role: 'assistant',\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: 'stop',\n timestamp: Date.now(),\n }\n}\n\ninterface GeminiUsageMetadata {\n promptTokenCount?: number\n candidatesTokenCount?: number\n cachedContentTokenCount?: number\n thoughtsTokenCount?: number\n totalTokenCount?: number\n}\n\ninterface GeminiStreamChunk {\n candidates?: Array<{\n content?: { role?: string; parts?: GeminiResponsePart[] }\n finishReason?: string\n }>\n usageMetadata?: GeminiUsageMetadata\n error?: unknown\n promptFeedback?: unknown\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object'\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction describeEmbeddedStreamFailure(\n chunk: GeminiStreamChunk,\n): string | undefined {\n if (chunk.error !== undefined) {\n const error = asRecord(chunk.error)\n if (!error) {\n const detail = typeof chunk.error === 'string' ? `: ${chunk.error}` : ''\n return `Antigravity stream error${detail}`\n }\n\n const labels: string[] = []\n if (typeof error.status === 'string') labels.push(error.status)\n if (typeof error.code === 'number' || typeof error.code === 'string') {\n labels.push(`code ${String(error.code)}`)\n }\n const details = Array.isArray(error.details) ? error.details : []\n const reason = details\n .map((detail) => asRecord(detail)?.reason)\n .find((value): value is string => typeof value === 'string')\n if (reason && !labels.includes(reason)) labels.push(reason)\n\n const label = labels.length > 0 ? ` (${labels.join(', ')})` : ''\n const message =\n typeof error.message === 'string' && error.message.length > 0\n ? `: ${error.message}`\n : ''\n return `Antigravity stream error${label}${message}`\n }\n\n const promptFeedback = asRecord(chunk.promptFeedback)\n if (!promptFeedback) return undefined\n const reason =\n typeof promptFeedback.blockReason === 'string'\n ? promptFeedback.blockReason\n : undefined\n const message =\n typeof promptFeedback.blockReasonMessage === 'string'\n ? promptFeedback.blockReasonMessage\n : undefined\n if (!reason && !message) return undefined\n\n return `Antigravity prompt blocked${reason ? ` (${reason})` : ''}${message ? `: ${message}` : ''}`\n}\n\n/**\n * Antigravity wraps each streamGenerateContent SSE chunk under a `response`\n * key: `data: {\"response\": {\"candidates\": [...], \"usageMetadata\": {...}}}`.\n * Unwrap it so downstream sees the plain Gemini chunk. MITM-verified against\n * agy 1.0.4 on 2026-06-13.\n */\nfunction unwrapChunk(raw: unknown): GeminiStreamChunk {\n if (raw && typeof raw === 'object' && 'response' in raw) {\n const inner = (raw as { response?: unknown }).response\n if (inner && typeof inner === 'object') {\n return inner as GeminiStreamChunk\n }\n }\n return raw as GeminiStreamChunk\n}\n\nexport interface GeminiResponsePart {\n text?: string\n thought?: boolean\n thoughtSignature?: string\n functionCall?: { name?: string; args?: JsonObject; id?: string }\n}\n\nexport interface GeminiToolCallState {\n pendingThoughtSignature?: string\n}\n\nexport function convertGeminiToolCallPart(\n part: GeminiResponsePart,\n state: GeminiToolCallState,\n): ToolCall | undefined {\n // Antigravity emits a batch signature on a preceding empty thought part;\n // native replay attaches it to the first function call in that batch.\n if (part.thought && !part.text && part.thoughtSignature) {\n state.pendingThoughtSignature = part.thoughtSignature\n }\n\n if (!part.functionCall) return undefined\n\n const thoughtSignature =\n part.thoughtSignature ?? state.pendingThoughtSignature\n state.pendingThoughtSignature = undefined\n\n return {\n type: 'toolCall',\n id: part.functionCall.id ?? `call_${crypto.randomUUID()}`,\n name: part.functionCall.name ?? '',\n arguments: part.functionCall.args ?? {},\n ...(thoughtSignature ? { thoughtSignature } : {}),\n }\n}\n\nexport function updateUsage(\n model: Model<Api>,\n output: AssistantMessage,\n usage?: GeminiUsageMetadata,\n): void {\n if (!usage) return\n const cacheRead = usage.cachedContentTokenCount ?? output.usage.cacheRead\n // Antigravity reports promptTokenCount as the full (uncached + cached) prompt.\n const promptTotal =\n usage.promptTokenCount ?? output.usage.input + output.usage.cacheRead\n output.usage.input = Math.max(0, promptTotal - cacheRead)\n // candidatesTokenCount excludes thinking; thoughtsTokenCount is billed as\n // output too. totalTokenCount = prompt + candidates + thoughts.\n if (\n usage.candidatesTokenCount !== undefined ||\n usage.thoughtsTokenCount !== undefined\n ) {\n output.usage.output =\n (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0)\n }\n output.usage.cacheRead = cacheRead\n output.usage.totalTokens =\n output.usage.input +\n output.usage.output +\n output.usage.cacheRead +\n output.usage.cacheWrite\n calculateCost(model, output.usage)\n}\n\nexport async function* parseGeminiSse(\n response: Response,\n): AsyncGenerator<GeminiStreamChunk> {\n if (!response.body) return\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n const parseFrame = function* (frame: string): Generator<GeminiStreamChunk> {\n for (const line of frame.split('\\n')) {\n if (!line.startsWith('data:')) continue\n const data = line.slice(5).trim()\n if (!data || data === '[DONE]') continue\n try {\n yield unwrapChunk(JSON.parse(data))\n } catch {\n // Ignore malformed SSE frames.\n }\n }\n }\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n // Antigravity uses CRLF line endings (`\\r\\n\\r\\n` frame separators);\n // normalize so a single boundary check works for both LF and CRLF.\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, '\\n')\n let boundary = buffer.indexOf('\\n\\n')\n while (boundary !== -1) {\n const frame = buffer.slice(0, boundary)\n buffer = buffer.slice(boundary + 2)\n boundary = buffer.indexOf('\\n\\n')\n yield* parseFrame(frame)\n }\n }\n // Flush any trailing frame that did not end with a blank-line separator.\n if (buffer.trim()) {\n yield* parseFrame(buffer)\n }\n } finally {\n reader.releaseLock()\n }\n}\n\nfunction getRequestSessionKey(\n context: Context,\n options?: SimpleStreamOptions,\n): string {\n if (options?.sessionId) {\n return options.sessionId\n }\n // Pi 0.86+ gives every leading system message timestamp 0. A session key\n // based on that value would make unrelated conversations share one request-\n // metadata entry. Use the first non-system message's timestamp instead.\n const firstTimestamp = context.messages.find(\n (message) => message.role !== 'system',\n )?.timestamp\n return firstTimestamp !== undefined\n ? `message:${firstTimestamp}`\n : FALLBACK_SESSION_KEY\n}\n\nexport function finalizePiAntigravityRequest(\n request: Record<string, unknown>,\n wireModel: string,\n scope: AgyRequestScope,\n): string {\n if (Array.isArray(request.tools) && request.tools.length > 0) {\n request.toolConfig = { functionCallingConfig: { mode: 'VALIDATED' } }\n }\n\n const metadata = buildAgyAgentRequestMetadata(\n scope.session,\n request,\n wireModel,\n scope.timestamp,\n { stepCountMode: 'cli' },\n )\n request.labels = metadata.labels\n request.sessionId = metadata.sessionId\n orderAgyRequestPayloadInPlace(request)\n return metadata.requestId\n}\n\nexport function resolvePiAntigravityModel(\n model: Model<Api>,\n reasoning?: ThinkingLevel,\n) {\n const lower = model.id.toLowerCase()\n const supportsAgyTiers =\n model.reasoning &&\n (lower.includes('gemini-3') ||\n (lower.includes('claude') &&\n (lower.includes('thinking') || /claude-(opus|sonnet)-5-5/.test(lower))))\n\n if (!supportsAgyTiers || !reasoning) {\n return resolveModelForHeaderStyle(model.id, 'antigravity')\n }\n\n const tier =\n reasoning === 'minimal' ? 'low' : reasoning === 'xhigh' ? 'high' : reasoning\n const baseModel = model.id.replace(/-(minimal|low|medium|high|xhigh)$/i, '')\n return resolveModelForHeaderStyle(`${baseModel}-${tier}`, 'antigravity')\n}\n\n/** A request body built once per logical request, before any credential is chosen. */\ninterface PreparedAntigravityRequest {\n readonly wireModel: string\n readonly requestId: string\n readonly request: Record<string, unknown>\n}\n\n/**\n * The bearer and Antigravity project for one physical send. Both must come\n * from the same source: the local login, or one vault receipt.\n */\nexport interface AntigravitySendCredential {\n readonly accessToken: string\n readonly projectId: string\n}\n\nfunction prepareAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n sessionKey: string\n}): PreparedAntigravityRequest {\n const resolved = resolvePiAntigravityModel(\n options.model,\n options.streamOptions?.reasoning,\n )\n const wireModel = resolved.actualModel\n if (isRetiredAgyModel(options.model.id) || isRetiredAgyModel(wireModel)) {\n throw new Error(RETIRED_AGY_MODEL_MESSAGE)\n }\n\n const request: Record<string, unknown> = {\n ...buildGeminiRequest(options.context, {\n provider: options.model.provider,\n model: options.model.id,\n }),\n }\n const generationConfig: Record<string, unknown> = {}\n\n if (resolved.thinkingLevel) {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingLevel: resolved.thinkingLevel,\n }\n } else if (typeof resolved.thinkingBudget === 'number') {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingBudget: resolved.thinkingBudget,\n }\n }\n\n const maxTokens = options.streamOptions?.maxTokens ?? options.model.maxTokens\n if (typeof maxTokens === 'number') {\n generationConfig.maxOutputTokens = maxTokens\n }\n applyAgyNativeGenerationConfig(wireModel, generationConfig)\n\n if (Object.keys(generationConfig).length > 0) {\n request.generationConfig = generationConfig\n }\n\n const requestScope = requestSessions.beginRequest(options.sessionKey)\n const requestId = finalizePiAntigravityRequest(\n request,\n wireModel,\n requestScope,\n )\n return { wireModel, requestId, request }\n}\n\n/** One physical send of a prepared request with one credential. */\nfunction dispatchAntigravityRequest(\n prepared: PreparedAntigravityRequest,\n credential: AntigravitySendCredential,\n signal: AbortSignal | null,\n): Promise<Response> {\n const envelope = {\n project: credential.projectId,\n requestId: prepared.requestId,\n request: prepared.request,\n model: prepared.wireModel,\n userAgent: 'antigravity',\n requestType: 'agent',\n }\n\n const url = `${ANTIGRAVITY_ENDPOINT}/v1internal:${STREAM_ACTION}?alt=sse`\n\n return fetchWithAgyCliTransport(\n url,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${credential.accessToken}`,\n 'Content-Type': 'application/json',\n 'User-Agent': buildAntigravityHarnessUserAgent(),\n 'Accept-Encoding': 'gzip',\n },\n body: JSON.stringify(envelope),\n },\n { signal },\n )\n}\n\n/** Local mode only; custody sends never reach this path. */\nasync function sendAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n accessToken: string\n sessionKey: string\n signal?: AbortSignal\n assertAdmission?: () => Promise<void>\n}): Promise<Response> {\n if (isRetiredAgyModel(options.model.id)) {\n throw new Error(RETIRED_AGY_MODEL_MESSAGE)\n }\n // Pi passes only the access token; the packed refresh\n // `refreshToken|projectId|managedProjectId` saved at getApiKey supplies\n // the managed project without a loadCodeAssist call per turn.\n const packedRefresh = getPackedRefresh(options.accessToken) ?? ''\n const projectContext = await ensureProjectContext({\n type: 'oauth',\n refresh: packedRefresh,\n access: options.accessToken,\n expires: Date.now() + 60_000,\n })\n\n const prepared = prepareAntigravityRequest(options)\n await options.assertAdmission?.()\n return dispatchAntigravityRequest(\n prepared,\n {\n accessToken: options.accessToken,\n projectId: projectContext.effectiveProjectId,\n },\n options.signal ?? options.streamOptions?.signal ?? null,\n )\n}\n\n/**\n * Vault (custody) mode: sends a prepared request through the vault. `send`\n * must call `dispatch` once per physical send, each time with the token and\n * project of a fresh vault receipt, and returns the response that was\n * finally served.\n */\nexport type AntigravityVaultSend = (\n dispatch: (\n credential: AntigravitySendCredential,\n signal?: AbortSignal,\n ) => Promise<Response>,\n signal: AbortSignal,\n) => Promise<Response>\n\ntype OpenAntigravityResponse = (\n sessionKey: string,\n signal: AbortSignal,\n selectedCredentials: Set<string>,\n) => Promise<Response>\n\nexport function streamCortexKitAntigravity(\n model: Model<Api>,\n context: Context,\n options?: SimpleStreamOptions,\n assertAdmission?: () => Promise<void>,\n): AssistantMessageEventStream {\n return runAntigravityStream(\n model,\n context,\n options,\n async (sessionKey, signal) => {\n await assertAdmission?.()\n const accessToken = options?.apiKey ?? ''\n if (!accessToken)\n throw new Error('Missing Antigravity OAuth access token')\n return sendAntigravityRequest({\n model,\n context,\n streamOptions: options,\n accessToken,\n sessionKey,\n signal,\n assertAdmission,\n })\n },\n )\n}\n\n/**\n * In vault mode, Pi's Google auth slot contains a fixed API-key marker,\n * not a real credential. Refuse any other resolved key so a stale local\n * login cannot enter this stream. Each physical request obtains its bearer\n * and project from the vault; local credentials and project caches are unused.\n */\nexport function createCortexKitAntigravityVaultStream(\n send: AntigravityVaultSend,\n placeholderKey: string,\n) {\n return (\n model: Model<Api>,\n context: Context,\n options?: SimpleStreamOptions,\n ): AssistantMessageEventStream =>\n runAntigravityStream(\n model,\n context,\n options,\n (sessionKey, signal, selectedCredentials) => {\n if (options?.apiKey !== placeholderKey)\n throw new Error(\n 'The native Google credential slot is not synchronized for vault mode. No request was sent.',\n )\n const prepared = prepareAntigravityRequest({\n model,\n context,\n streamOptions: options,\n sessionKey,\n })\n return send(async (credential, sendSignal) => {\n selectedCredentials.add(credential.accessToken)\n try {\n return await dispatchAntigravityRequest(\n prepared,\n credential,\n sendSignal ?? signal,\n )\n } catch (error) {\n throw redactCredentialError(error, [...selectedCredentials])\n }\n }, signal)\n },\n )\n}\n\nfunction runAntigravityStream(\n model: Model<Api>,\n context: Context,\n options: SimpleStreamOptions | undefined,\n open: OpenAntigravityResponse,\n): AssistantMessageEventStream {\n const stream = createAssistantMessageEventStream()\n\n void (async () => {\n const output = createOutput(model)\n const selectedCredentials = new Set<string>(\n options?.apiKey ? [options.apiKey] : [],\n )\n stream.push({ type: 'start', partial: output })\n let response: Response | undefined\n let requestAbort: AbortController | undefined\n let chunkIterator: AsyncIterator<GeminiStreamChunk> | undefined\n let detachCaller = () => {}\n\n try {\n const sessionKey = getRequestSessionKey(context, options)\n requestAbort = new AbortController()\n detachCaller = forwardAbort(options?.signal, requestAbort)\n response = await open(\n sessionKey,\n requestAbort.signal,\n selectedCredentials,\n )\n\n if (!response.ok) {\n throw new Error(\n `Antigravity request failed: HTTP ${response.status} ${await response.text()}`,\n )\n }\n\n const content = output.content as Array<\n TextContent | ThinkingContent | ToolCall\n >\n const toolCallState: GeminiToolCallState = {}\n let textIndex = -1\n let thinkingIndex = -1\n let terminalSeen = false\n\n const closeText = () => {\n if (textIndex === -1) return\n const block = content[textIndex]\n if (block?.type === 'text') {\n stream.push({\n type: 'text_end',\n contentIndex: textIndex,\n content: block.text,\n partial: output,\n })\n }\n textIndex = -1\n }\n\n const closeThinking = () => {\n if (thinkingIndex === -1) return\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n stream.push({\n type: 'thinking_end',\n contentIndex: thinkingIndex,\n content: block.thinking,\n partial: output,\n })\n }\n thinkingIndex = -1\n }\n\n chunkIterator = parseGeminiSse(response)[Symbol.asyncIterator]()\n let terminalFinishReason: string | undefined\n while (true) {\n const next = terminalSeen\n ? await nextWithTimeout(\n chunkIterator,\n TRAILING_USAGE_TIMEOUT_MS,\n () => requestAbort?.abort(),\n )\n : await chunkIterator.next()\n if (!next) break\n if (next.done) break\n\n const chunk = next.value\n const embeddedFailure = describeEmbeddedStreamFailure(chunk)\n if (embeddedFailure) throw new Error(embeddedFailure)\n updateUsage(model, output, chunk.usageMetadata)\n\n if (terminalSeen) {\n if (chunk.usageMetadata) break\n continue\n }\n\n const candidate = chunk.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n if (\n !part.thought &&\n !part.functionCall &&\n !part.text &&\n part.thoughtSignature\n ) {\n const block = textIndex === -1 ? undefined : content[textIndex]\n if (block?.type === 'text') {\n block.textSignature = part.thoughtSignature\n } else {\n toolCallState.pendingThoughtSignature = part.thoughtSignature\n }\n continue\n }\n\n const toolCall = convertGeminiToolCallPart(part, toolCallState)\n if (toolCall) {\n closeText()\n closeThinking()\n content.push(toolCall)\n const idx = content.length - 1\n stream.push({\n type: 'toolcall_start',\n contentIndex: idx,\n partial: output,\n })\n stream.push({\n type: 'toolcall_end',\n contentIndex: idx,\n toolCall,\n partial: output,\n })\n output.stopReason = 'toolUse'\n continue\n }\n\n if (part.thought) {\n if (typeof part.text !== 'string' || part.text.length === 0)\n continue\n closeText()\n if (thinkingIndex === -1) {\n content.push({\n type: 'thinking',\n thinking: '',\n ...(part.thoughtSignature\n ? { thinkingSignature: part.thoughtSignature }\n : {}),\n })\n thinkingIndex = content.length - 1\n stream.push({\n type: 'thinking_start',\n contentIndex: thinkingIndex,\n partial: output,\n })\n }\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n block.thinking += part.text\n if (part.thoughtSignature)\n block.thinkingSignature = part.thoughtSignature\n stream.push({\n type: 'thinking_delta',\n contentIndex: thinkingIndex,\n delta: part.text,\n partial: output,\n })\n }\n continue\n }\n\n if (typeof part.text === 'string' && part.text.length > 0) {\n closeThinking()\n if (textIndex === -1) {\n const textSignature =\n part.thoughtSignature ?? toolCallState.pendingThoughtSignature\n toolCallState.pendingThoughtSignature = undefined\n content.push({\n type: 'text',\n text: '',\n ...(textSignature ? { textSignature } : {}),\n })\n textIndex = content.length - 1\n stream.push({\n type: 'text_start',\n contentIndex: textIndex,\n partial: output,\n })\n }\n const block = content[textIndex]\n if (block?.type === 'text') {\n block.text += part.text\n if (part.thoughtSignature)\n block.textSignature = part.thoughtSignature\n stream.push({\n type: 'text_delta',\n contentIndex: textIndex,\n delta: part.text,\n partial: output,\n })\n }\n }\n }\n\n if (candidate?.finishReason) {\n closeText()\n closeThinking()\n if (output.stopReason !== 'toolUse') {\n output.stopReason = mapFinishReason(candidate.finishReason)\n }\n terminalSeen = true\n terminalFinishReason = candidate.finishReason\n const needsTrailingUsage =\n model.id.toLowerCase().includes('gpt-oss') && !chunk.usageMetadata\n if (!needsTrailingUsage) break\n }\n }\n\n if (terminalSeen) {\n try {\n await chunkIterator.return?.(undefined)\n } catch (error) {\n if (!requestAbort.signal.aborted) throw error\n }\n await response.body?.cancel().catch(() => {})\n }\n\n if (options?.signal?.aborted) throw new Error('Request was aborted')\n if (!terminalSeen) {\n throw new Error(\n 'Antigravity stream ended without a terminal candidate response',\n )\n }\n if (content.length === 0) {\n throw new Error(\n `Antigravity returned an empty response${terminalFinishReason ? ` (${terminalFinishReason})` : ''}`,\n )\n }\n\n stream.push({\n type: 'done',\n reason: output.stopReason as 'stop' | 'length' | 'toolUse',\n message: output,\n })\n if (output.stopReason === 'stop' || output.stopReason === 'length') {\n requestSessions.completeExecution(sessionKey)\n }\n stream.end()\n } catch (error) {\n requestAbort?.abort()\n await chunkIterator?.return?.(undefined).catch(() => {})\n await response?.body?.cancel().catch(() => {})\n output.stopReason = options?.signal?.aborted ? 'aborted' : 'error'\n output.errorMessage = redactCredentialText(\n error instanceof Error ? error.message : String(error),\n [...selectedCredentials],\n )\n stream.push({ type: 'error', reason: output.stopReason, error: output })\n stream.end()\n } finally {\n detachCaller()\n }\n })()\n\n return stream\n}\n", "import { toGeminiSchema } from '@cortexkit/antigravity-auth-core'\nimport type {\n AssistantMessage,\n Context,\n ImageContent,\n Message,\n TextContent,\n Tool,\n ToolResultMessage,\n} from '@earendil-works/pi-ai'\n// Namespace import so the transcript helpers can be feature-detected: a named\n// import of an export that an older installed pi-ai lacks fails at module link\n// time and would stop the extension from loading at all.\nimport * as piAi from '@earendil-works/pi-ai'\n\n/** Gemini `contents` part shapes. */\ntype GeminiPart =\n | { text: string; thought?: boolean; thoughtSignature?: string }\n | { inlineData: { mimeType: string; data: string } }\n | {\n functionCall: { name: string; args: Record<string, unknown>; id: string }\n thoughtSignature?: string\n }\n | {\n functionResponse: {\n name: string\n response: Record<string, unknown>\n id: string\n }\n }\n\ninterface GeminiContent {\n role: 'user' | 'model'\n parts: GeminiPart[]\n}\n\ninterface GeminiTool {\n functionDeclarations: Array<{\n name: string\n description: string\n parameters?: unknown\n }>\n}\n\nexport interface GeminiRequest {\n contents: GeminiContent[]\n tools?: GeminiTool[]\n systemInstruction?: { parts: GeminiPart[] }\n}\n\nfunction sanitize(text: string): string {\n return text.replace(/[\\uD800-\\uDFFF]/gu, '\\uFFFD')\n}\n\nfunction convertUserParts(\n content: Array<TextContent | ImageContent>,\n): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const item of content) {\n if (item.type === 'text') {\n if (item.text) parts.push({ text: sanitize(item.text) })\n } else if (item.type === 'image' && item.data) {\n parts.push({ inlineData: { mimeType: item.mimeType, data: item.data } })\n }\n }\n return parts\n}\n\nfunction convertAssistantParts(\n message: AssistantMessage,\n preserveSignedHistory: boolean,\n): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const block of message.content) {\n if (block.type === 'thinking') {\n if (preserveSignedHistory && block.thinking) {\n parts.push({\n text: sanitize(block.thinking),\n thought: true,\n ...(block.thinkingSignature\n ? { thoughtSignature: block.thinkingSignature }\n : {}),\n })\n }\n } else if (block.type === 'text' && block.text.trim()) {\n parts.push({\n text: sanitize(block.text),\n ...(preserveSignedHistory && block.textSignature\n ? { thoughtSignature: block.textSignature }\n : {}),\n })\n } else if (block.type === 'toolCall') {\n parts.push({\n functionCall: {\n name: block.name,\n args: (block.arguments ?? {}) as Record<string, unknown>,\n id: block.id,\n },\n ...(preserveSignedHistory && block.thoughtSignature\n ? { thoughtSignature: block.thoughtSignature }\n : {}),\n })\n }\n }\n return parts\n}\n\nfunction toolResultResponse(\n message: ToolResultMessage,\n): Record<string, unknown> {\n const text = message.content\n .filter((item): item is TextContent => item.type === 'text')\n .map((item) => item.text)\n .join('\\n')\n if (message.isError) {\n return { error: text || 'Error' }\n }\n return { output: text }\n}\n\nexport interface BuildGeminiRequestOptions {\n provider?: string\n model?: string\n}\n\nfunction isSameTargetModel(\n message: AssistantMessage,\n options: BuildGeminiRequestOptions | undefined,\n): boolean {\n if (!options?.provider || !options.model) return true\n return (\n message.provider === options.provider && message.model === options.model\n )\n}\n\nfunction convertMessages(\n messages: Message[],\n options?: BuildGeminiRequestOptions,\n): GeminiContent[] {\n const contents: GeminiContent[] = []\n const callMatchesTarget = new Map<string, boolean>()\n\n for (const message of messages) {\n if (message?.role !== 'assistant') continue\n const matchesTarget = isSameTargetModel(message, options)\n for (const block of message.content) {\n if (block.type === 'toolCall') {\n callMatchesTarget.set(block.id, matchesTarget)\n }\n }\n }\n\n for (const message of messages) {\n if (!message) continue\n\n // System messages carry the prompt and tool state, which\n // resolveInstructionState replays into systemInstruction and tools.\n if (message.role === 'system') continue\n\n if (message.role === 'user') {\n const parts =\n typeof message.content === 'string'\n ? message.content.trim()\n ? [{ text: sanitize(message.content) }]\n : []\n : convertUserParts(\n message.content as Array<TextContent | ImageContent>,\n )\n if (parts.length) contents.push({ role: 'user', parts })\n continue\n }\n\n if (message.role === 'assistant') {\n const parts = convertAssistantParts(\n message,\n isSameTargetModel(message, options),\n )\n if (parts.length) contents.push({ role: 'model', parts })\n continue\n }\n\n if (message.role === 'toolResult') {\n const role =\n callMatchesTarget.get(message.toolCallId) === true ? 'model' : 'user'\n const part: GeminiPart = {\n functionResponse: {\n name: message.toolName,\n response: toolResultResponse(message),\n id: message.toolCallId,\n },\n }\n // Gemini groups consecutive function responses into one user turn.\n const last = contents[contents.length - 1]\n if (\n last &&\n last.role === role &&\n last.parts.every((p) => 'functionResponse' in p)\n ) {\n last.parts.push(part)\n } else {\n contents.push({ role, parts: [part] })\n }\n }\n }\n\n return contents\n}\n\nfunction convertTools(tools: Tool[] | undefined): GeminiTool[] | undefined {\n if (!tools?.length) return undefined\n return [\n {\n // Match the agy wire format (MITM-verified): field name is `parameters`\n // (not `parametersJsonSchema`) and schemas are sanitized to Gemini shape\n // (UPPERCASE types, unsupported keywords stripped) via core's toGeminiSchema.\n functionDeclarations: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: toGeminiSchema(tool.parameters),\n })),\n },\n ]\n}\n\ninterface InstructionState {\n systemPrompt: string\n tools: Tool[]\n}\n\n/**\n * Resolve the system prompt and tool set the request must carry.\n *\n * Pi 0.86+ hands providers a transcript whose system messages hold the prompt\n * and tools: the leading one declares them and later ones append text, patch\n * named sections, and add or remove tools. When the transcript has any system\n * message it is the only authority, replayed with pi-ai's own helpers, so a\n * prompt or tool set emptied by later system messages stays empty even if\n * flat `systemPrompt`/`tools` fields are also present. Older Pi runtimes pass\n * a flat `Context` with no system messages, which is read as-is.\n */\nfunction resolveInstructionState(context: Context): InstructionState {\n if (!context.messages.some((message) => message?.role === 'system')) {\n return {\n systemPrompt: context.systemPrompt ?? '',\n tools: context.tools ?? [],\n }\n }\n\n if (\n typeof piAi.getCurrentSystemPrompt !== 'function' ||\n typeof piAi.getCurrentTools !== 'function'\n ) {\n // Dropping the system messages would silently send a request with no\n // prompt and no tools, so refuse instead.\n throw new Error(\n 'Pi transcript contains system messages but the installed @earendil-works/pi-ai does not export getCurrentSystemPrompt/getCurrentTools (requires >= 0.86)',\n )\n }\n\n return {\n systemPrompt: piAi.getCurrentSystemPrompt(context.messages),\n tools: piAi.getCurrentTools(context.messages),\n }\n}\n\n/**\n * Convert a pi request context into a Gemini `generateContent` request body\n * (the inner `request` object of the Antigravity envelope). Accepts both the\n * transcript form Pi 0.86+ passes to providers and the flat `Context` of\n * older runtimes.\n */\nexport function buildGeminiRequest(\n context: Context,\n options?: BuildGeminiRequestOptions,\n): GeminiRequest {\n const request: GeminiRequest = {\n contents: convertMessages(context.messages, options),\n }\n\n const { systemPrompt, tools } = resolveInstructionState(context)\n\n const geminiTools = convertTools(tools)\n if (geminiTools) request.tools = geminiTools\n\n if (systemPrompt.trim()) {\n request.systemInstruction = {\n parts: [{ text: sanitize(systemPrompt) }],\n }\n }\n\n return request\n}\n", "/**\n * Pi's custody request path. Each physical send takes its bearer and\n * Antigravity project from one fresh vault receipt, so a revoked account or\n * a moved project applies on the next send and a 401 is reported against the\n * exact record version that was served. Nothing is cached or refreshed\n * locally. Each send checks the vault mode file. Account discovery and\n * changes use the vault source's enrollment checks, without reading Pi's\n * saved Google login.\n */\n\nimport { existsSync } from 'node:fs'\n\nimport {\n type AntigravityVaultAccountSource,\n type CommonAuthClaustrumModule,\n type CommonAuthCommandsModule,\n type CommonAuthPiSlotModule,\n createAntigravityVaultAccountSource,\n enrollmentAuthority,\n loadCommonAuthClaustrum,\n type VaultRouteRef,\n} from '@cortexkit/antigravity-auth-core'\nimport type {\n ClaustrumEnrollmentConnection,\n ClaustrumScopedClient,\n} from '@cortexkit/antigravity-auth-core/common-auth/claustrum'\n\nimport {\n getPiAntigravityVaultDir,\n getPiAntigravityVaultModeFile,\n getPiAntigravityVaultRosterFile,\n} from './paths.ts'\nimport type { AntigravityVaultSend } from './stream.ts'\nimport {\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n PI_ANTIGRAVITY_VAULT_HOST,\n type PiVaultAccountChoice,\n type PiVaultAccountsPort,\n type PiVaultModeRead,\n type PiVaultModeRecord,\n PiVaultSetup,\n readPiVaultMode,\n} from './vault-setup.ts'\n\n/** The shared vault account source operations Pi's request path and setup use. */\nexport type PiVaultAccountSource = Pick<\n AntigravityVaultAccountSource,\n 'refresh' | 'routes' | 'send' | 'decline' | 'accept'\n>\n\ntype PiVaultRouteRef = VaultRouteRef\n\nexport class PiVaultSendError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PiVaultSendError'\n }\n}\n\nexport interface PiVaultRequestPathOptions {\n /** Read this host's vault enrollment and account-source choice before each operation; never reuse an earlier request's state. */\n readMode: () => PiVaultModeRead | Promise<PiVaultModeRead>\n /** The shared vault account source, created once on first use. */\n source: () => Promise<PiVaultAccountSource>\n}\n\n/** Require current vault-mode settings before opening the account source; refuse local or unreadable settings. */\nfunction requireCustody(read: PiVaultModeRead): PiVaultModeRecord {\n if (!read.ok)\n throw new PiVaultSendError(\n `Antigravity vault mode is unclear (${read.reason}). Choose a mode in the Vault section of the Antigravity menu.`,\n )\n if (read.record.mode !== 'custody')\n throw new PiVaultSendError(\n 'Antigravity is not served from the vault. Switch in the Vault section of the Antigravity menu.',\n )\n return read.record\n}\n\nfunction selectRoute(\n routes: readonly PiVaultRouteRef[],\n routeId: string | undefined,\n): PiVaultRouteRef {\n if (routeId !== undefined) {\n const selected = routes.find((route) => route.routeId === routeId)\n if (!selected)\n throw new PiVaultSendError(\n 'The chosen vault account is no longer available (declined, removed or changed). Choose another in the Vault section of the Antigravity menu.',\n )\n return selected\n }\n const [only, ...rest] = routes\n if (!only)\n throw new PiVaultSendError(\n 'The vault serves Pi no Antigravity accounts yet.',\n )\n if (rest.length > 0)\n throw new PiVaultSendError(\n 'The vault serves Pi several Antigravity accounts. Choose one in the Vault section of the Antigravity menu.',\n )\n return only\n}\n\n/** Custody checks that run before discovery, a roster change or a send. */\nasync function openCustody(\n options: PiVaultRequestPathOptions,\n): Promise<{ record: PiVaultModeRecord; source: PiVaultAccountSource }> {\n const record = requireCustody(await options.readMode())\n const source = await options.source()\n return { record, source }\n}\n\n/** The send function the custody stream uses for every model request. */\nexport function createPiVaultSend(\n options: PiVaultRequestPathOptions,\n): AntigravityVaultSend {\n return async (dispatch, signal) => {\n const { record, source } = await openCustody(options)\n signal.throwIfAborted()\n let routes = source.routes()\n if (routes.length === 0) {\n // Load the vault roster before selecting an account for this request.\n await source.refresh()\n signal.throwIfAborted()\n routes = source.routes()\n }\n // Capture the route before any further await, so the send is bound to\n // the account the roster named now, not to whatever later sits there.\n const ref = selectRoute(routes, record.routeId)\n return source.send(ref, dispatch, { site: 'model', signal })\n }\n}\n\n/** Vault accounts for the setup command, with declined ones marked. */\nexport function createPiVaultAccountsPort(\n options: PiVaultRequestPathOptions,\n): PiVaultAccountsPort {\n // Kept from the last listing so decline/accept act on the account the user\n // picked, never on a route id that now names another account.\n let lastRows = new Map<string, PiVaultRouteRef>()\n\n const refFor = (routeId: string): PiVaultRouteRef => {\n const ref = lastRows.get(routeId)\n if (!ref)\n throw new PiVaultSendError(\n 'That vault account is no longer listed. Open the Vault section again.',\n )\n return ref\n }\n\n return {\n list: async () => {\n const { source } = await openCustody(options)\n const roster = await source.refresh()\n const rows = new Map<string, PiVaultRouteRef>()\n const choices: PiVaultAccountChoice[] = []\n for (const row of roster?.rows ?? []) {\n if (!row.accountIdentity) continue\n const ref: PiVaultRouteRef = {\n routeId: row.routeId,\n credentialId: row.credentialId,\n accountIdentity: row.accountIdentity,\n label: row.label,\n ...(row.email !== undefined && { email: row.email }),\n }\n rows.set(row.routeId, ref)\n const declined = (roster?.declined ?? []).some(\n (entry) =>\n entry.credentialId === row.credentialId &&\n (entry.accountIdentity === undefined ||\n entry.accountIdentity === row.accountIdentity),\n )\n choices.push({\n routeId: row.routeId,\n label: row.label,\n ...(row.email !== undefined && { email: row.email }),\n declined,\n })\n }\n lastRows = rows\n return choices\n },\n decline: async (routeId) => {\n const { source } = await openCustody(options)\n await source.decline(refFor(routeId))\n },\n accept: async (routeId) => {\n const { source } = await openCustody(options)\n await source.accept(refFor(routeId))\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Production composition\n// ---------------------------------------------------------------------------\n\n/**\n * I/O seams of the vault composition. Pi's default entry passes none: the\n * vault client connects through the connection file Claustrum publishes,\n * Pi's auth slot is read from Pi's auth.json, and files live under Pi's\n * vault directory. Tests replace only the client transport and file paths.\n */\nexport interface PiVaultSeams {\n connect?: () => Promise<ClaustrumScopedClient>\n connectEnrollment?: () => Promise<ClaustrumEnrollmentConnection>\n readHostSlot?: () => unknown\n nativeAuthPath?: string\n nativeStashPath?: string\n loadPiSlot?: () => Promise<CommonAuthPiSlotModule>\n vaultDir?: string\n modeFile?: string\n rosterFile?: string\n loadClaustrum?: () => Promise<CommonAuthClaustrumModule>\n /** Commands library loader for the menu (tests capture the renderer call). */\n loadCommands?: () => Promise<CommonAuthCommandsModule>\n}\n\nexport interface PiVaultRuntime {\n readMode(): PiVaultModeRead\n readonly requestPath: PiVaultRequestPathOptions\n setup(): Promise<PiVaultSetup>\n}\n\nasync function claustrumConnectionFile(): Promise<string> {\n const { resolveClaustrumConnectionPath } = await import(\n '@cortexkit/claustrum-client'\n )\n return resolveClaustrumConnectionPath()\n}\n\nfunction memoize<T>(load: () => Promise<T>): () => Promise<T> {\n let pending: Promise<T> | undefined\n return () => {\n pending ??= load().catch((error: unknown) => {\n pending = undefined\n throw error\n })\n return pending\n }\n}\n\n/**\n * Build Pi's vault composition. Nothing is loaded or connected here; the\n * vault library and the shared account source are created on the first\n * custody send or setup action.\n */\nexport function createPiVaultRuntime(\n readHostSlot: () => unknown,\n seams: PiVaultSeams = {},\n onModeChanged?: (record: PiVaultModeRecord) => void | Promise<void>,\n): PiVaultRuntime {\n const vaultDir = seams.vaultDir ?? getPiAntigravityVaultDir()\n const modeFile = seams.modeFile ?? getPiAntigravityVaultModeFile()\n const rosterFile = seams.rosterFile ?? getPiAntigravityVaultRosterFile()\n const loadClaustrum = seams.loadClaustrum ?? loadCommonAuthClaustrum\n const readMode = () => readPiVaultMode(modeFile)\n\n const source = memoize(async (): Promise<PiVaultAccountSource> => {\n const claustrum = await loadClaustrum()\n const { tokenPath } = claustrum.hostEnrollmentPaths({\n stateDir: vaultDir,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n })\n return createAntigravityVaultAccountSource({\n claustrum,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n rosterPath: rosterFile,\n tokenPath,\n connect:\n seams.connect ??\n (async () =>\n claustrum.connectClaustrumScopedClient({\n connectionFile: await claustrumConnectionFile(),\n })),\n // The vault serves this host only once setup has stored an approved\n // enrollment token; Pi's own send path also requires custody mode.\n isCustodyActive: () => existsSync(tokenPath),\n // Pi reads the HTTP status of each send itself.\n reporterSource: 'direct',\n })\n })\n\n const setup = memoize(async () => {\n const claustrum = await loadClaustrum()\n return new PiVaultSetup({\n claustrum,\n stateDir: vaultDir,\n modeFile,\n readHostSlot,\n ...(onModeChanged && { onModeChanged }),\n connectEnrollment:\n seams.connectEnrollment ??\n (async () =>\n claustrum.connectClaustrumEnrollmentClient({\n connectionFile: await claustrumConnectionFile(),\n })),\n })\n })\n\n return {\n readMode,\n setup,\n requestPath: {\n readMode: async () => {\n const settings = await setup()\n const status = await settings.sourceStatus()\n const authority = await enrollmentAuthority(\n settings.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (authority === 'local' && status.mode === 'custody')\n throw new PiVaultSendError(\n 'Vault enrollment is not active. No request was sent.',\n )\n if (status.mode === 'unreadable')\n throw new PiVaultSendError(\n 'Vault enrollment or source settings cannot be read.',\n )\n return {\n ok: true,\n record: {\n version: 1,\n mode: status.mode,\n ...(status.selectedRouteId\n ? { routeId: status.selectedRouteId }\n : {}),\n },\n }\n },\n source,\n },\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { join } from 'node:path'\nimport {\n ANTIGRAVITY_PROVIDER_ID,\n authorizeAntigravity,\n enrollmentAuthority,\n exchangeAntigravity,\n getPublicModelDefinitions,\n loadCommonAuthPiSlot,\n refreshAntigravityToken,\n} from '@cortexkit/antigravity-auth-core'\nimport type { PluginExtraSection } from '@cortexkit/antigravity-auth-core/common-auth/commands'\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n} from '@earendil-works/pi-ai'\nimport {\n type ExtensionAPI,\n getAgentDir,\n type ProviderConfig,\n readStoredCredential,\n} from '@earendil-works/pi-coding-agent'\n\nimport {\n createPiAntigravityAccountSections,\n type PiAntigravityAccountSections,\n registerPiAntigravityCommand,\n} from './commands.ts'\nimport { rememberPackedRefresh } from './credential-cache.ts'\nimport { getPiAntigravityVaultDir } from './paths.ts'\nimport {\n createCortexKitAntigravityVaultStream,\n streamCortexKitAntigravity,\n} from './stream.ts'\nimport {\n createPiVaultSection,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n type PiVaultModeRead,\n type PiVaultModeRecord,\n PiVaultSetupError,\n} from './vault-setup.ts'\nimport {\n createPiVaultAccountsPort,\n createPiVaultRuntime,\n createPiVaultSend,\n type PiVaultSeams,\n} from './vault-source.ts'\n\n/** Refresh value of the vault placeholder login; local mode must never refresh it. */\nexport const CUSTODY_PLACEHOLDER_REFRESH_PREFIX = 'claustrum-tombstone:v1:'\n\n/** Non-secret key that lets Pi list custody models without a login; never sent. */\nexport const CUSTODY_PROVIDER_KEY_MARKER = 'antigravity-vault-custody'\n\nfunction textImageInput(): Array<'text' | 'image'> {\n return ['text', 'image']\n}\n\nasync function loginAntigravity(\n callbacks: OAuthLoginCallbacks,\n): Promise<OAuthCredentials> {\n const auth = await authorizeAntigravity()\n callbacks.onAuth({ url: auth.url })\n const code = await callbacks.onPrompt({\n message: 'Paste the Antigravity OAuth callback URL or code:',\n })\n\n // The state (PKCE verifier + project) is carried in the authorize URL; reuse\n // it so the code exchange can recover the verifier.\n const authState = new URL(auth.url).searchParams.get('state') ?? ''\n\n // Accept either a raw code or a full redirect URL with ?code= and &state=.\n let rawCode = code.trim()\n let state = authState\n try {\n const url = new URL(rawCode)\n const codeParam = url.searchParams.get('code')\n const stateParam = url.searchParams.get('state')\n if (codeParam) rawCode = codeParam\n if (stateParam) state = stateParam\n } catch {\n // Not a URL \u2014 treat the input as a bare authorization code.\n }\n\n const result = await exchangeAntigravity(rawCode, state)\n if (result.type !== 'success') {\n throw new Error(`Antigravity OAuth exchange failed: ${result.error}`)\n }\n\n return {\n refresh: result.refresh,\n access: result.access,\n expires: result.expires,\n }\n}\n\nasync function refreshAntigravityCredentials(\n credentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n // Local mode refreshes Pi's own login only. The vault placeholder is not a\n // login: refreshing it would send it to Google as a refresh token.\n if (credentials.refresh.startsWith(CUSTODY_PLACEHOLDER_REFRESH_PREFIX))\n throw new Error(\n 'Pi holds the Antigravity vault placeholder, not a login. Run /login, or serve Antigravity from the vault.',\n )\n // Stored refresh is `refreshToken|projectId|managedProjectId`.\n const refreshToken = credentials.refresh.split('|')[0] ?? credentials.refresh\n const refreshed = await refreshAntigravityToken(refreshToken)\n // Preserve the project segments packed into the stored refresh string.\n const projectSegments = credentials.refresh.includes('|')\n ? credentials.refresh.slice(credentials.refresh.indexOf('|'))\n : ''\n return {\n refresh: `${refreshed.refresh}${projectSegments}`,\n access: refreshed.access,\n expires: refreshed.expires,\n }\n}\n\nfunction publicModels(): NonNullable<ProviderConfig['models']> {\n return (\n Object.values(getPublicModelDefinitions())\n // Pi's AssistantMessage protocol has no image-output content type. Keep\n // generation-only image routes out of the chat model catalog rather than\n // advertising output that the stream contract cannot represent.\n .filter((model) => !model.modalities.output.includes('image'))\n .map((model) => ({\n id: model.id,\n name: model.name,\n reasoning: model.reasoning,\n input: textImageInput(),\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n contextWindow: model.limit.context,\n maxTokens: model.limit.output,\n }))\n )\n}\n\nfunction localProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n assertLocalAdmission: () => Promise<void>,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit OAuth)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n oauth: {\n name: 'Google Antigravity (CortexKit)',\n login: async (callbacks) => {\n await assertLocalAdmission()\n return loginAntigravity(callbacks)\n },\n refreshToken: async (credentials) => {\n await assertLocalAdmission()\n return refreshAntigravityCredentials(credentials)\n },\n getApiKey: (credentials) => {\n // Bridge the packed refresh (refreshToken|projectId|managedProjectId)\n // to the stream, which otherwise only receives the bare access token.\n rememberPackedRefresh(credentials.access, credentials.refresh)\n return credentials.access\n },\n },\n streamSimple: (model, context, options) =>\n streamCortexKitAntigravity(model, context, options, assertLocalAdmission),\n }\n}\n\n/** Custody (or unreadable mode): no OAuth, so Pi never refreshes locally. */\nfunction custodyProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n send: ReturnType<typeof createPiVaultSend>,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit vault)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n apiKey: CUSTODY_PROVIDER_KEY_MARKER,\n streamSimple: createCortexKitAntigravityVaultStream(\n send,\n CUSTODY_PROVIDER_KEY_MARKER,\n ),\n }\n}\n\n/**\n * Registered while the native credential slot cannot be synchronized with the\n * chosen mode. It keeps the same provider id and models, so Pi neither falls\n * back to its built-in Google catalog nor lists a second provider. It has no\n * OAuth, so Pi never refreshes or rewrites the native login, and every request\n * fails with the reason before anything is sent.\n */\nfunction refusingProviderConfig(\n models: NonNullable<ProviderConfig['models']>,\n reason: string,\n): ProviderConfig {\n return {\n name: 'Google Antigravity (CortexKit, unavailable)',\n baseUrl: 'https://cloudcode-pa.googleapis.com',\n api: 'google-generative-ai',\n models,\n apiKey: CUSTODY_PROVIDER_KEY_MARKER,\n streamSimple: createCortexKitAntigravityVaultStream(async () => {\n throw new PiVaultSetupError(\n `${reason} Resolve it from /antigravity; Antigravity requests are refused until then. No request was sent.`,\n )\n }, CUSTODY_PROVIDER_KEY_MARKER),\n }\n}\n\n/**\n * The vault runtime Pi composes custody from: the public `./claustrum` entry\n * of `@cortexkit/common-auth`, the setup-only enrollment connection, and the\n * shared Antigravity vault account source for the `pi` host.\n */\nexport interface PiAntigravityExtension {\n /**\n * The Vault section for the shared command menu, where enrollment, mode\n * switching and account choice happen.\n */\n readonly vaultSection: PluginExtraSection\n /** Pi's own Accounts, Quota, Routing and Limits sections for the same menu. */\n readonly accountSections: PiAntigravityAccountSections\n}\n\n/**\n * Register the Antigravity provider for the mode the user chose: Pi's own\n * login (local, the default) or the vault (custody). Changing the mode in\n * the Vault section re-registers the same provider id, so Pi never lists two.\n * `seams` replaces only I/O (vault client transport, file paths, auth slot)\n * for tests; Pi's default entry passes none.\n */\nexport async function registerCortexKitPiAntigravity(\n pi: Pick<ExtensionAPI, 'registerProvider' | 'registerCommand'> &\n Partial<Pick<ExtensionAPI, 'on'>>,\n seams: PiVaultSeams = {},\n): Promise<PiAntigravityExtension> {\n const models = publicModels()\n const readHostSlot =\n seams.readHostSlot ?? (() => readStoredCredential(ANTIGRAVITY_PROVIDER_ID))\n let refreshRegistry: (() => void) | undefined\n const vault = createPiVaultRuntime(readHostSlot, seams, async () => {\n try {\n await synchronizeSlot()\n } finally {\n refreshRegistry?.()\n }\n })\n const send = createPiVaultSend(vault.requestPath)\n\n const register = (mode: PiVaultModeRead) => {\n const local = mode.ok && mode.record.mode === 'local'\n pi.registerProvider(\n ANTIGRAVITY_PROVIDER_ID,\n local\n ? localProviderConfig(models, assertLocalAdmission)\n : custodyProviderConfig(models, send),\n )\n }\n const currentMode = async (): Promise<PiVaultModeRecord> => {\n const setup = await vault.setup()\n const status = await setup.sourceStatus()\n const authority = await enrollmentAuthority(\n setup.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (authority === 'unreadable' || status.mode === 'unreadable') {\n throw new PiVaultSetupError(\n 'Vault enrollment or source settings cannot be read. Local credentials remain unavailable.',\n )\n }\n if (authority === 'vault')\n return {\n version: 1,\n mode: 'custody',\n ...(status.selectedRouteId ? { routeId: status.selectedRouteId } : {}),\n }\n if (status.mode !== 'local')\n throw new PiVaultSetupError(\n 'Vault enrollment must be approved before activating vault credentials.',\n )\n return { version: 1, mode: 'local' }\n }\n const assertLocalAdmission = async () => {\n if ((await currentMode()).mode !== 'local')\n throw new PiVaultSetupError(\n 'Vault enrollment excludes local login, refresh and request execution.',\n )\n }\n const synchronizeSlotOnce = async () => {\n try {\n await swapSlotForMode()\n } catch (error) {\n // Leave the provider registered but refusing, so a failed swap neither\n // serves from the wrong credential nor unregisters the models.\n pi.registerProvider(\n ANTIGRAVITY_PROVIDER_ID,\n refusingProviderConfig(\n models,\n error instanceof Error ? error.message : String(error),\n ),\n )\n throw error\n }\n }\n // Startup, session_start and every mode change synchronize the slot. Run them\n // one at a time: each reads the mode when it starts, so the run that\n // registers last is the one that read the newest mode.\n let synchronizing: Promise<void> = Promise.resolve()\n const synchronizeSlot = (): Promise<void> => {\n const run = synchronizing.then(synchronizeSlotOnce)\n synchronizing = run.catch(() => {})\n return run\n }\n const swapSlotForMode = async () => {\n const mode = await currentMode()\n const { openPiSlot } = await (seams.loadPiSlot ?? loadCommonAuthPiSlot)()\n const slot = openPiSlot({\n authPath: seams.nativeAuthPath ?? join(getAgentDir(), 'auth.json'),\n stashPath:\n seams.nativeStashPath ??\n join(\n seams.vaultDir ?? getPiAntigravityVaultDir(),\n 'google-login-stash.json',\n ),\n provider: ANTIGRAVITY_PROVIDER_ID,\n placeholderKey: CUSTODY_PROVIDER_KEY_MARKER,\n })\n if (mode.mode === 'custody') await slot.enterVault()\n else if ((await slot.exitVault()) === 'conflict')\n throw new PiVaultSetupError(\n 'The native Google login changed. It was not overwritten; restore the saved login after resolving the conflict.',\n )\n const after = await currentMode()\n if (after.mode !== mode.mode)\n throw new PiVaultSetupError(\n 'Vault enrollment changed while the credential slot was being synchronized. The account source was not activated.',\n )\n register({ ok: true, record: after })\n }\n // Pi's first catalog refresh reads auth.json to decide which models are usable.\n // Install the vault marker before the factory returns so discovery and the\n // first request cannot refresh the dormant Google login. A failed swap has\n // registered the refusing provider; the factory still resolves so the\n // /antigravity menu below, which holds the remedies, stays registered.\n await synchronizeSlot().catch(() => {})\n pi.on?.('session_start', async (_event, context) => {\n refreshRegistry = () => context.modelRegistry.refresh()\n try {\n await synchronizeSlot()\n } finally {\n refreshRegistry()\n }\n })\n\n const accounts = createPiVaultAccountsPort(vault.requestPath)\n const extension: PiAntigravityExtension = {\n accountSections: createPiAntigravityAccountSections({\n setup: vault.setup,\n accounts: () => accounts,\n }),\n vaultSection: createPiVaultSection({\n setup: vault.setup,\n accounts: () => accounts,\n }),\n }\n registerPiAntigravityCommand(pi, {\n sections: extension.accountSections,\n extras: [extension.vaultSection],\n ...(seams.loadCommands && { loadCommands: seams.loadCommands }),\n })\n return extension\n}\n\nexport default async function cortexKitPiAntigravityAuth(\n pi: ExtensionAPI,\n): Promise<void> {\n await registerCortexKitPiAntigravity(pi)\n}\n", "/**\n * Pi's `/antigravity` command: the core's shared Antigravity menu in its\n * host-sections mode, drawn with Pi's extension UI by the library's Pi\n * renderer. Pi has one account at a time and no account rows, so it supplies\n * all four account slots itself. The commands library loads on the first\n * invocation, and every invocation builds a fresh menu.\n */\n\nimport {\n ANTIGRAVITY_MENU_COMMAND,\n type AntigravityMenuSections,\n type CommonAuthCommandsModule,\n createAntigravityCommandMenu,\n loadCommonAuthCommands,\n} from '@cortexkit/antigravity-auth-core'\nimport type {\n ItemDefinition,\n PluginExtraSection,\n} from '@cortexkit/antigravity-auth-core/common-auth/commands'\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent'\n\nimport {\n opaqueItemId,\n type PiVaultAccountChoice,\n type PiVaultAccountsPort,\n type PiVaultSetup,\n type PiVaultSetupStatus,\n vaultAccountName,\n} from './vault-setup.ts'\n\nexport interface PiAntigravityCommandOptions {\n sections: AntigravityMenuSections\n extras: readonly PluginExtraSection[]\n /** Loads the commands library; defaults to the core's lazy loader. */\n loadCommands?: () => Promise<CommonAuthCommandsModule>\n}\n\nexport function registerPiAntigravityCommand(\n pi: Pick<ExtensionAPI, 'registerCommand'>,\n options: PiAntigravityCommandOptions,\n): void {\n const loadCommands = options.loadCommands ?? loadCommonAuthCommands\n pi.registerCommand(ANTIGRAVITY_MENU_COMMAND, {\n description:\n 'Google Antigravity: the account Pi serves, and the Claustrum vault',\n handler: async (_args, ctx) => {\n const commands = await loadCommands()\n const menu = createAntigravityCommandMenu({\n commands,\n source: 'sections',\n sections: options.sections,\n extras: options.extras,\n })\n await commands.runPiCommandMenu(menu, ctx.ui, {\n sessionId: ctx.sessionManager.getSessionId(),\n })\n },\n })\n}\n\n// ---------------------------------------------------------------------------\n// Pi's own Accounts, Quota, Routing and Limits sections\n// ---------------------------------------------------------------------------\n\n/**\n * The menu's four account slots, built from what Pi actually has: one\n * account at a time (its own login, or one vault account), no pool, no\n * rotation and no recorded quota. Nothing here pretends to be a pool row.\n */\nexport type PiAntigravityAccountSections = AntigravityMenuSections\n\nexport interface PiAntigravityAccountSectionsOptions {\n setup: () => Promise<PiVaultSetup>\n accounts: () => PiVaultAccountsPort\n}\n\n/** The vault account Pi sends with now, when custody can name one. */\nfunction servingAccount(\n status: PiVaultSetupStatus,\n accounts: readonly PiVaultAccountChoice[],\n): PiVaultAccountChoice | undefined {\n const available = accounts.filter((account) => !account.declined)\n if (status.selectedRouteId !== undefined)\n return available.find(\n (account) => account.routeId === status.selectedRouteId,\n )\n return available.length === 1 ? available[0] : undefined\n}\n\nasync function custodyAccounts(\n status: PiVaultSetupStatus,\n options: PiAntigravityAccountSectionsOptions,\n): Promise<{ list: readonly PiVaultAccountChoice[]; problem?: string }> {\n if (status.mode !== 'custody' || status.enrollment.state !== 'approved')\n return { list: [] }\n try {\n return { list: await options.accounts().list() }\n } catch (error) {\n return {\n list: [],\n problem: `Vault accounts unavailable: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n}\n\nfunction localLoginLine(status: PiVaultSetupStatus): string {\n switch (status.hostSlot) {\n case 'dormant':\n return 'The native Pi login is dormant while vault enrollment controls serving.'\n case 'login':\n return \"Signed in with Pi's own login. Pi's /login replaces it and /logout removes it.\"\n case 'placeholder':\n return 'Pi holds the vault placeholder, not a login. Run /login, or serve from the vault in the Vault section.'\n case 'empty':\n return \"Not signed in. Run Pi's /login to sign in.\"\n }\n}\n\nexport function createPiAntigravityAccountSections(\n options: PiAntigravityAccountSectionsOptions,\n): PiAntigravityAccountSections {\n return {\n accounts: {\n title: 'Accounts',\n build: async () => {\n const status = await (await options.setup()).status()\n if (status.mode === 'unreadable')\n return {\n lines: [\n `The vault mode file is unreadable (${status.modeProblem ?? 'unknown problem'}); Pi serves nothing until a mode is chosen in the Vault section.`,\n ],\n }\n if (status.mode === 'local')\n return {\n lines: [\n \"Pi serves Antigravity from its own login, one account, kept in Pi's auth store.\",\n localLoginLine(status),\n ],\n }\n const { list, problem } = await custodyAccounts(status, options)\n const serving = servingAccount(status, list)\n const items: ItemDefinition[] = list.map((account) => ({\n id: opaqueItemId(account.routeId),\n label: vaultAccountName(list, account),\n detail: account.declined\n ? 'declined on this host'\n : account === serving\n ? 'serving Pi'\n : 'available',\n }))\n return {\n lines: [\n 'Pi serves Antigravity from the vault, one account at a time. Choose, decline or accept accounts in the Vault section.',\n ...(status.hostSlot === 'login'\n ? [\n 'Conflict: Pi also holds its own login. Requests are refused until /logout or a switch back to the local login.',\n ]\n : []),\n ...(problem ? [problem] : []),\n ],\n items,\n }\n },\n },\n quota: {\n title: 'Quota',\n build: () => ({\n lines: [\n \"Pi does not record Antigravity quota. A request Google refuses for quota fails with Google's own error.\",\n ],\n }),\n },\n routing: {\n title: 'Routing',\n build: async () => {\n const status = await (await options.setup()).status()\n if (status.mode === 'unreadable')\n return {\n lines: [\n 'Vault enrollment authority is unreadable; requests are refused. Recover or Disconnect in the Vault section.',\n ],\n }\n if (status.mode !== 'custody')\n return {\n lines: [\n \"Every request uses Pi's own login. There is no account rotation.\",\n ],\n }\n const { list } = await custodyAccounts(status, options)\n const serving = servingAccount(status, list)\n return {\n lines: [\n serving\n ? `Every request uses ${vaultAccountName(list, serving)}, with a fresh token and project from the vault for each send. There is no account rotation.`\n : 'No single vault account is chosen, so requests are refused. Choose one in the Vault section. There is no account rotation.',\n ],\n }\n },\n },\n limits: {\n title: 'Limits',\n build: () => ({\n lines: [\n 'Pi has no per-account limits for Antigravity: with one account there is nothing to fall back to.',\n ],\n }),\n },\n }\n}\n", "/**\n * Setup for serving Pi's Antigravity provider from the Claustrum vault\n * (\"custody\") instead of Pi's own login (\"local\"). The two never serve\n * together. Enrollment as `antigravity-auth-pi` runs only from the Vault\n * menu section, never from a model request; the enrollment token stays in\n * the vault library's owner-only file and Pi's auth slot is only read.\n */\n\nimport { createHash, randomBytes } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport type { CommonAuthClaustrumModule } from '@cortexkit/antigravity-auth-core'\nimport {\n ANTIGRAVITY_PROVIDER_ID,\n enrollmentAuthority,\n} from '@cortexkit/antigravity-auth-core'\nimport { writeJsonAtomic } from '@cortexkit/antigravity-auth-core/atomic-write'\nimport type {\n ClaustrumEnrollmentConnection,\n ClaustrumEnrollmentPaths,\n ClaustrumEnrollmentStatus,\n HostSlotContent,\n} from '@cortexkit/antigravity-auth-core/common-auth/claustrum'\nimport type {\n ActionDefinition,\n ActionOutcome,\n ItemDefinition,\n PluginExtraSection,\n} from '@cortexkit/antigravity-auth-core/common-auth/commands'\n\n/** Pi's provider id; also the key of its auth slot in Pi's auth.json. */\nexport const PI_ANTIGRAVITY_PROVIDER_ID = ANTIGRAVITY_PROVIDER_ID\n/** The host name this extension enrolls under, one enrollment per host. */\nexport const PI_ANTIGRAVITY_VAULT_HOST = 'pi'\n/** The enrollment name the operator sees and approves for Pi. */\nexport const PI_ANTIGRAVITY_ENROLLMENT_NAME = 'antigravity-auth-pi'\n\n// ---------------------------------------------------------------------------\n// Mode file\n// ---------------------------------------------------------------------------\n\nexport type PiAntigravityMode = 'local' | 'custody'\n\n/**\n * What Pi serves Antigravity from. `routeId` names the vault account the\n * user picked; it is a roster route id, never credential material.\n */\nexport interface PiVaultModeRecord {\n readonly version: 1\n readonly mode: PiAntigravityMode\n readonly routeId?: string\n}\n\nexport type PiVaultModeRead =\n | { readonly ok: true; readonly record: PiVaultModeRecord }\n | { readonly ok: false; readonly reason: string }\n\nconst LOCAL_MODE: PiVaultModeRecord = Object.freeze({\n version: 1,\n mode: 'local',\n})\n\nfunction parseModeRecord(raw: unknown): PiVaultModeRecord | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw))\n return undefined\n const record = raw as Record<string, unknown>\n for (const key of Object.keys(record))\n if (key !== 'version' && key !== 'mode' && key !== 'routeId')\n return undefined\n if (record.version !== 1) return undefined\n if (record.mode !== 'local' && record.mode !== 'custody') return undefined\n if (record.routeId === undefined)\n return Object.freeze({ version: 1, mode: record.mode })\n if (typeof record.routeId !== 'string' || record.routeId.trim() === '')\n return undefined\n return Object.freeze({\n version: 1,\n mode: record.mode,\n routeId: record.routeId,\n })\n}\n\n/**\n * Read the mode file. A missing file is local mode, so an extension that\n * was never set up keeps serving its single login. A file that exists but\n * cannot be understood is reported, not guessed: the caller refuses to serve\n * rather than pick a mode the user may not have chosen.\n */\nexport function readPiVaultMode(path: string): PiVaultModeRead {\n let text: string\n try {\n text = readFileSync(path, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException | null)?.code === 'ENOENT')\n return { ok: true, record: LOCAL_MODE }\n return { ok: false, reason: 'the vault mode file could not be read' }\n }\n let raw: unknown\n try {\n raw = JSON.parse(text)\n } catch {\n return { ok: false, reason: 'the vault mode file is not valid JSON' }\n }\n const record = parseModeRecord(raw)\n return record\n ? { ok: true, record }\n : { ok: false, reason: 'the vault mode file has an unknown shape' }\n}\n\nexport async function writePiVaultMode(\n path: string,\n record: PiVaultModeRecord,\n): Promise<void> {\n const value: PiVaultModeRecord =\n record.routeId === undefined\n ? { version: 1, mode: record.mode }\n : { version: 1, mode: record.mode, routeId: record.routeId }\n await writeJsonAtomic(path, value)\n}\n\n// ---------------------------------------------------------------------------\n// Vault accounts as setup sees them\n// ---------------------------------------------------------------------------\n\n/** An account shown in the vault menu; declined accounts are excluded from request selection. */\nexport interface PiVaultAccountChoice {\n readonly routeId: string\n /** Display label from the vault roster; may hold the account's email. */\n readonly label: string\n readonly email?: string\n readonly declined: boolean\n}\n\n/**\n * Vault account discovery and selection used by the setup menu.\n * These operations become available after the operator approves access.\n */\nexport interface PiVaultAccountsPort {\n /** Reload and save the list of permitted vault accounts, then return it to the menu. */\n list(): Promise<readonly PiVaultAccountChoice[]>\n decline(routeId: string): Promise<void>\n accept(routeId: string): Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// Setup controller\n// ---------------------------------------------------------------------------\n\nexport interface PiVaultSetupStatus {\n readonly mode: PiAntigravityMode | 'unreadable'\n readonly modeProblem?: string\n readonly selectedRouteId?: string\n readonly enrollment: ClaustrumEnrollmentStatus\n readonly hostSlot: HostSlotContent | 'dormant'\n}\n\nexport interface PiVaultSetupOptions {\n claustrum: CommonAuthClaustrumModule\n /** Pi's vault directory (see `getPiAntigravityVaultDir`). */\n stateDir: string\n /** Pi's vault mode file (see `getPiAntigravityVaultModeFile`). */\n modeFile: string\n /** Read Pi's own Google credential record, only when local accounts are selected. */\n readHostSlot: () => unknown\n /** Opens the setup-only enrollment connection to the vault. */\n connectEnrollment: () => Promise<ClaustrumEnrollmentConnection>\n /** Re-register the Google provider after its selected account source changes. */\n onModeChanged?: (record: PiVaultModeRecord) => void | Promise<void>\n now?: () => number\n}\n\n/** A setup action refused before anything changed, with a message for the user. */\nexport class PiVaultSetupError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PiVaultSetupError'\n }\n}\n\nexport class PiVaultSetup {\n readonly #options: PiVaultSetupOptions\n readonly paths: ClaustrumEnrollmentPaths\n\n constructor(options: PiVaultSetupOptions) {\n this.#options = options\n this.paths = options.claustrum.hostEnrollmentPaths({\n stateDir: options.stateDir,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n })\n }\n\n #hostSlot(): HostSlotContent {\n return this.#options.claustrum.classifyHostSlot(\n this.#options.readHostSlot(),\n PI_ANTIGRAVITY_PROVIDER_ID,\n )\n }\n\n /** Read vault approval and local/vault settings without opening Pi's Google credentials. */\n async sourceStatus(): Promise<Omit<PiVaultSetupStatus, 'hostSlot'>> {\n const mode = readPiVaultMode(this.#options.modeFile)\n const enrollment = await this.#options.claustrum\n .readClaustrumEnrollmentStatus(this.paths, PI_ANTIGRAVITY_ENROLLMENT_NAME)\n .catch(\n (): ClaustrumEnrollmentStatus => ({\n state: 'blocked',\n proposedName: PI_ANTIGRAVITY_ENROLLMENT_NAME,\n code: 'unreadable-state',\n }),\n )\n const authority = await enrollmentAuthority(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n this.#options.claustrum,\n )\n return {\n ...(authority !== 'local'\n ? {\n mode:\n authority === 'vault'\n ? ('custody' as const)\n : ('unreadable' as const),\n ...(mode.ok &&\n mode.record.routeId !== undefined && {\n selectedRouteId: mode.record.routeId,\n }),\n }\n : mode.ok\n ? {\n mode: mode.record.mode,\n ...(mode.record.routeId !== undefined && {\n selectedRouteId: mode.record.routeId,\n }),\n }\n : { mode: 'unreadable' as const, modeProblem: mode.reason }),\n enrollment,\n }\n }\n\n /** Inspect the native login only when local accounts are selected. */\n async status(): Promise<PiVaultSetupStatus> {\n const source = await this.sourceStatus()\n return {\n ...source,\n hostSlot: source.mode === 'local' ? this.#hostSlot() : 'dormant',\n }\n }\n\n /**\n * Propose Pi to the vault or poll its recorded proposal. Clear a denied or\n * blocked request before starting again. Only setup actions call this method.\n */\n async connectStep(): Promise<ClaustrumEnrollmentStatus> {\n const client = await this.#options.connectEnrollment()\n try {\n const manager = new this.#options.claustrum.ClaustrumEnrollmentManager({\n client,\n paths: this.paths,\n proposedName: PI_ANTIGRAVITY_ENROLLMENT_NAME,\n ...(this.#options.now && { now: this.#options.now }),\n })\n const current = await manager.status()\n if (current.state === 'denied' || current.state === 'blocked')\n await manager.resetTerminal()\n const reconciled = await manager.reconcile()\n if (reconciled.state === 'approved') {\n const saved = readPiVaultMode(this.#options.modeFile)\n await this.useVault(\n saved.ok && saved.record.mode === 'custody'\n ? saved.record.routeId\n : undefined,\n )\n }\n return reconciled\n } finally {\n client.close()\n }\n }\n\n /**\n * Select the vault account used for requests after the operator approves\n * enrollment. Await the host's Google credential-slot transition before\n * returning, so provider registration cannot race it.\n */\n async useVault(routeId?: string): Promise<PiVaultModeRecord> {\n const enrollment =\n await this.#options.claustrum.readClaustrumEnrollmentStatus(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (enrollment.state !== 'approved')\n throw new PiVaultSetupError(\n 'Pi is not enrolled with the vault yet. Request access and wait for the operator to approve it first.',\n )\n if (routeId !== undefined && routeId.trim() === '')\n throw new PiVaultSetupError('Choose a vault account to use.')\n const record: PiVaultModeRecord =\n routeId === undefined\n ? { version: 1, mode: 'custody' }\n : { version: 1, mode: 'custody', routeId }\n await writePiVaultMode(this.#options.modeFile, record)\n await this.#options.onModeChanged?.(record)\n return record\n }\n\n /** Use Pi's local login only after vault enrollment has been disconnected. */\n async useLocal(): Promise<PiVaultModeRecord> {\n if (\n (await enrollmentAuthority(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n this.#options.claustrum,\n )) !== 'local'\n ) {\n throw new PiVaultSetupError(\n 'Disconnect vault enrollment before using local accounts.',\n )\n }\n await writePiVaultMode(this.#options.modeFile, LOCAL_MODE)\n await this.#options.onModeChanged?.(LOCAL_MODE)\n return LOCAL_MODE\n }\n\n /**\n * Forget this host's enrollment (token and ceremony state) and go back to\n * local mode. The vault keeps the enrollment approved until the operator\n * revokes it there.\n */\n async disconnect(): Promise<void> {\n const result = await this.#options.claustrum.disconnectClaustrumEnrollment(\n this.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (result === 'busy')\n throw new PiVaultSetupError(\n 'Vault enrollment is busy; disconnect did not change it.',\n )\n await writePiVaultMode(this.#options.modeFile, LOCAL_MODE)\n await this.#options.onModeChanged?.(LOCAL_MODE)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Rendering through Pi's command and dialog surfaces\n// ---------------------------------------------------------------------------\n\nfunction describeEnrollment(status: ClaustrumEnrollmentStatus): string {\n switch (status.state) {\n case 'idle':\n return 'not requested'\n case 'pending':\n return status.retryCode\n ? `waiting for operator approval (retrying: ${status.retryCode})`\n : 'waiting for operator approval'\n case 'approved':\n return `approved as ${status.approvedName ?? status.proposedName}`\n case 'denied':\n return 'denied by the operator'\n case 'blocked':\n return `blocked (${status.code})`\n case 'unavailable':\n return `vault unavailable (${status.code})`\n case 'busy':\n return 'another setup step is running'\n }\n}\n\nfunction describeHostSlot(slot: HostSlotContent): string {\n switch (slot) {\n case 'login':\n return 'signed in with a Pi login'\n case 'placeholder':\n return 'holds the vault placeholder'\n case 'empty':\n return 'empty'\n }\n}\n\n/** Setup-menu status text with no credentials or Antigravity project identifiers. */\nexport function formatPiVaultSetupStatus(status: PiVaultSetupStatus): string[] {\n const lines = [\n `Mode: ${\n status.mode === 'custody'\n ? 'vault (custody)'\n : status.mode === 'local'\n ? 'local Pi login'\n : `unreadable (${status.modeProblem ?? 'unknown problem'})`\n }`,\n `Enrollment (${PI_ANTIGRAVITY_ENROLLMENT_NAME}): ${describeEnrollment(status.enrollment)}`,\n status.hostSlot === 'dormant'\n ? 'Pi auth slot: dormant (not read)'\n : `Pi auth slot: ${describeHostSlot(status.hostSlot)}`,\n ]\n if (status.selectedRouteId !== undefined)\n lines.push('Vault account: a specific account is chosen (marked below)')\n if (status.mode === 'local' && status.hostSlot === 'placeholder')\n lines.push(\n 'Conflict: local mode has no login to serve. Run /login or switch to the vault.',\n )\n return lines\n}\n\n// ---------------------------------------------------------------------------\n// Vault section of the shared command menu\n// ---------------------------------------------------------------------------\n\nexport interface PiVaultSectionOptions {\n /** The setup controller; created on first use so the vault library loads lazily. */\n setup: () => Promise<PiVaultSetup>\n /** Vault account actions, available only after the approved account source is constructed. */\n accounts?: () => PiVaultAccountsPort | undefined\n /** How Request access polls for the operator's approval (tests shorten it). */\n wait?: PiVaultWaitOptions\n}\n\nexport interface PiVaultWaitOptions {\n pollIntervalMs?: number\n timeoutMs?: number\n sleep?: (ms: number) => Promise<void>\n}\n\n/**\n * Menu payloads leave this process (the shared menu may hand them to a\n * renderer), so a vault account's item id is an opaque digest of its route\n * id under a per-process salt: stable while Pi runs, so an apply finds the\n * same account the user saw, but never the raw route id.\n */\nconst ITEM_ID_SALT = randomBytes(16)\n\n/**\n * A vault account's display name in the menu: its position in the vault's\n * list. The roster label is usually the account's email, which must not\n * leave this process in a menu payload; positions are shown, never accepted\n * as targets.\n */\nexport function vaultAccountName(\n listed: readonly PiVaultAccountChoice[],\n account: PiVaultAccountChoice,\n): string {\n return `Vault account ${listed.indexOf(account) + 1}`\n}\n\nexport function opaqueItemId(routeId: string): string {\n return `vault-${createHash('sha256').update(ITEM_ID_SALT).update(routeId).digest('hex').slice(0, 16)}`\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction refused(error: unknown): ActionOutcome {\n if (error instanceof PiVaultSetupError)\n return { ok: false, text: error.message, code: 'vault-refused' }\n throw error\n}\n\n/** Poll the enrollment until it leaves `pending`/`busy` or the wait ends. */\nasync function waitForApproval(\n setup: PiVaultSetup,\n wait: PiVaultWaitOptions = {},\n): Promise<ClaustrumEnrollmentStatus> {\n const sleep =\n wait.sleep ??\n ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)))\n const interval = wait.pollIntervalMs ?? 2_000\n const deadline = Date.now() + (wait.timeoutMs ?? 10 * 60_000)\n let status = await setup.connectStep()\n while (status.state === 'pending' || status.state === 'busy') {\n if (Date.now() >= deadline) return status\n await sleep(interval)\n status = await setup.connectStep()\n }\n return status\n}\n\n/**\n * The Vault section of Pi's command menu: mode and enrollment status, the\n * vault accounts with use/decline/accept, requesting access (the only place\n * enrollment runs), switching between the vault and the local Pi login, and\n * forgetting the enrollment. Shows status only, never the enrollment token,\n * and never a raw route id, roster label or email.\n */\nexport function createPiVaultSection(\n options: PiVaultSectionOptions,\n): PluginExtraSection {\n return {\n id: 'vault',\n title: 'Vault',\n build: async () => {\n const setup = await options.setup()\n const status = await setup.status()\n const approved = status.enrollment.state === 'approved'\n const lines = formatPiVaultSetupStatus(status)\n const items: ItemDefinition[] = []\n const port = approved ? options.accounts?.() : undefined\n if (port) {\n try {\n const listed = await port.list()\n for (const account of listed) {\n const name = vaultAccountName(listed, account)\n const serving =\n status.mode === 'custody' &&\n status.selectedRouteId === account.routeId\n items.push({\n id: opaqueItemId(account.routeId),\n label: name,\n detail: account.declined\n ? 'declined on this host'\n : serving\n ? 'serving Pi'\n : 'available',\n actions: account.declined\n ? [\n {\n id: 'accept',\n label: 'Accept on this host',\n run: async () => {\n await port.accept(account.routeId)\n return `${name} is accepted on this host.`\n },\n },\n ]\n : [\n {\n id: 'use',\n label: 'Serve Pi from this account',\n run: async () => {\n try {\n await setup.useVault(account.routeId)\n } catch (error) {\n return refused(error)\n }\n return `Pi now serves Antigravity from ${name}.`\n },\n },\n {\n id: 'decline',\n label: 'Decline on this host',\n description:\n 'It stays in the vault and in this list, and is never sent from this host until accepted again.',\n run: async () => {\n await port.decline(account.routeId)\n return `${name} is declined on this host.`\n },\n },\n ],\n })\n }\n } catch (error) {\n lines.push(`Vault accounts unavailable: ${errorText(error)}`)\n }\n }\n\n const actions: ActionDefinition[] = []\n if (!approved)\n actions.push({\n id: 'request-access',\n label: 'Request vault access',\n description: `Asks the vault to enroll Pi as ${PI_ANTIGRAVITY_ENROLLMENT_NAME}; the operator approves it in the vault.`,\n run: async ({ invocation }) => {\n const step = await setup.connectStep()\n if (step.state !== 'pending' && step.state !== 'busy')\n return {\n ok: step.state === 'approved',\n text: `Enrollment: ${describeEnrollment(step)}`,\n }\n // The approval happens outside Pi; keep polling and report to\n // the session that asked.\n void waitForApproval(setup, options.wait)\n .then((final) => {\n invocation.notify(\n `Enrollment: ${describeEnrollment(final)}`,\n final.state === 'approved' ? 'info' : 'warning',\n )\n })\n .catch((error: unknown) => {\n invocation.notify(\n `Requesting vault access failed: ${errorText(error)}`,\n 'error',\n )\n })\n return {\n ok: true,\n text: `Enrollment: ${describeEnrollment(step)}. You are told here when the operator decides.`,\n }\n },\n })\n if (approved && status.mode !== 'custody')\n actions.push({\n id: 'use-vault',\n label: 'Serve Pi from the vault',\n run: async () => {\n try {\n await setup.useVault(status.selectedRouteId)\n } catch (error) {\n return refused(error)\n }\n return 'Pi now serves Antigravity from the vault.'\n },\n })\n if (\n status.mode !== 'local' &&\n (status.enrollment.state === 'idle' ||\n status.enrollment.state === 'pending' ||\n status.enrollment.state === 'denied')\n )\n actions.push({\n id: 'use-local',\n label: 'Serve Pi from its own login',\n run: async () => {\n await setup.useLocal()\n return 'Pi now serves Antigravity from its own login. Run /login if it has none.'\n },\n })\n if (status.enrollment.state !== 'idle')\n actions.push({\n id: 'forget',\n label: 'Forget vault enrollment',\n description:\n \"Deletes Pi's enrollment token and returns to the local login. The operator can still revoke the enrollment in the vault.\",\n irreversible: true,\n confirm: `Forget the ${PI_ANTIGRAVITY_ENROLLMENT_NAME} enrollment? Using the vault again needs a new approval.`,\n run: async () => {\n await setup.disconnect()\n return 'Vault enrollment forgotten; Pi serves Antigravity from its own login.'\n },\n })\n\n return { lines, items, actions }\n },\n }\n}\n", "/**\n * In-process bridge for the packed refresh string.\n *\n * pi's provider framework extracts the bearer token via `oauth.getApiKey` and\n * passes only that access token to `streamSimple` (as `options.apiKey`). The\n * packed refresh (`refreshToken|projectId|managedProjectId`) that login/refresh\n * resolved is therefore not visible to the stream. We cache it here, keyed by\n * the access token, so the stream can recover the managed-project context and\n * avoid a redundant loadCodeAssist round-trip on every turn.\n */\n\nconst packedRefreshByAccessToken = new Map<string, string>()\n// Single-account extension: keep the map tiny.\nconst MAX_ENTRIES = 4\n\nexport function rememberPackedRefresh(\n accessToken: string,\n packedRefresh: string,\n): void {\n if (!accessToken) return\n if (packedRefreshByAccessToken.has(accessToken)) {\n packedRefreshByAccessToken.delete(accessToken)\n } else if (packedRefreshByAccessToken.size >= MAX_ENTRIES) {\n const oldest = packedRefreshByAccessToken.keys().next().value\n if (oldest !== undefined) packedRefreshByAccessToken.delete(oldest)\n }\n packedRefreshByAccessToken.set(accessToken, packedRefresh)\n}\n\nexport function getPackedRefresh(accessToken: string): string | undefined {\n return packedRefreshByAccessToken.get(accessToken)\n}\n", "import { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\nexport function getPiConfigDir(): string {\n return process.env.PI_AGENT_DIR?.trim() || join(homedir(), '.pi', 'agent')\n}\n\nexport function getPiAntigravityAuthFile(): string {\n return (\n process.env.PI_ANTIGRAVITY_AUTH_FILE?.trim() ||\n join(getPiConfigDir(), 'antigravity-accounts.json')\n )\n}\n\n/**\n * Directory for Pi's Claustrum vault files (enrollment token and ceremony\n * state, the vault roster, the custody mode file). It sits next to the\n * account file in its own subdirectory so common-auth can restrict\n * its permissions without changing Pi's configuration directory.\n */\nexport function getPiAntigravityVaultDir(): string {\n return join(dirname(getPiAntigravityAuthFile()), 'antigravity-auth-vault')\n}\n\n/** Non-secret settings file selecting local or vault credentials for Pi requests. */\nexport function getPiAntigravityVaultModeFile(): string {\n return join(getPiAntigravityVaultDir(), 'pi-mode.json')\n}\n\n/** List of vault accounts Pi may use; contains account references, never tokens. */\nexport function getPiAntigravityVaultRosterFile(): string {\n return join(getPiAntigravityVaultDir(), 'pi-roster.json')\n}\n", "import {\n type AgyRequestScope,\n AgyRequestSessionStore,\n ANTIGRAVITY_ENDPOINT,\n applyAgyNativeGenerationConfig,\n buildAgyAgentRequestMetadata,\n buildAntigravityHarnessUserAgent,\n ensureProjectContext,\n fetchWithAgyCliTransport,\n forwardAbort,\n isRetiredAgyModel,\n orderAgyRequestPayloadInPlace,\n RETIRED_AGY_MODEL_MESSAGE,\n redactCredentialError,\n redactCredentialText,\n resolveModelForHeaderStyle,\n} from '@cortexkit/antigravity-auth-core'\nimport {\n type Api,\n type AssistantMessage,\n type AssistantMessageEventStream,\n type Context,\n calculateCost,\n createAssistantMessageEventStream,\n type JsonObject,\n type Model,\n type SimpleStreamOptions,\n type StopReason,\n type TextContent,\n type ThinkingContent,\n type ThinkingLevel,\n type ToolCall,\n} from '@earendil-works/pi-ai'\n\nimport { buildGeminiRequest } from './convert.ts'\nimport { getPackedRefresh } from './credential-cache.ts'\n\nconst STREAM_ACTION = 'streamGenerateContent'\nconst FALLBACK_SESSION_KEY = '__default__'\nconst TRAILING_USAGE_TIMEOUT_MS = 1_000\nconst requestSessions = new AgyRequestSessionStore('')\n\nasync function nextWithTimeout<T>(\n iterator: AsyncIterator<T>,\n timeoutMs: number,\n onTimeout: () => void,\n): Promise<IteratorResult<T> | undefined> {\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n iterator.next(),\n new Promise<undefined>((resolve) => {\n timer = setTimeout(() => {\n onTimeout()\n resolve(undefined)\n }, timeoutMs)\n }),\n ])\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\nfunction mapFinishReason(reason: string | null | undefined): StopReason {\n switch (reason) {\n case 'STOP':\n return 'stop'\n case 'MAX_TOKENS':\n return 'length'\n default:\n return reason ? 'stop' : 'stop'\n }\n}\n\nfunction createOutput(model: Model<Api>): AssistantMessage {\n return {\n role: 'assistant',\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: 'stop',\n timestamp: Date.now(),\n }\n}\n\ninterface GeminiUsageMetadata {\n promptTokenCount?: number\n candidatesTokenCount?: number\n cachedContentTokenCount?: number\n thoughtsTokenCount?: number\n totalTokenCount?: number\n}\n\ninterface GeminiStreamChunk {\n candidates?: Array<{\n content?: { role?: string; parts?: GeminiResponsePart[] }\n finishReason?: string\n }>\n usageMetadata?: GeminiUsageMetadata\n error?: unknown\n promptFeedback?: unknown\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object'\n ? (value as Record<string, unknown>)\n : undefined\n}\n\nfunction describeEmbeddedStreamFailure(\n chunk: GeminiStreamChunk,\n): string | undefined {\n if (chunk.error !== undefined) {\n const error = asRecord(chunk.error)\n if (!error) {\n const detail = typeof chunk.error === 'string' ? `: ${chunk.error}` : ''\n return `Antigravity stream error${detail}`\n }\n\n const labels: string[] = []\n if (typeof error.status === 'string') labels.push(error.status)\n if (typeof error.code === 'number' || typeof error.code === 'string') {\n labels.push(`code ${String(error.code)}`)\n }\n const details = Array.isArray(error.details) ? error.details : []\n const reason = details\n .map((detail) => asRecord(detail)?.reason)\n .find((value): value is string => typeof value === 'string')\n if (reason && !labels.includes(reason)) labels.push(reason)\n\n const label = labels.length > 0 ? ` (${labels.join(', ')})` : ''\n const message =\n typeof error.message === 'string' && error.message.length > 0\n ? `: ${error.message}`\n : ''\n return `Antigravity stream error${label}${message}`\n }\n\n const promptFeedback = asRecord(chunk.promptFeedback)\n if (!promptFeedback) return undefined\n const reason =\n typeof promptFeedback.blockReason === 'string'\n ? promptFeedback.blockReason\n : undefined\n const message =\n typeof promptFeedback.blockReasonMessage === 'string'\n ? promptFeedback.blockReasonMessage\n : undefined\n if (!reason && !message) return undefined\n\n return `Antigravity prompt blocked${reason ? ` (${reason})` : ''}${message ? `: ${message}` : ''}`\n}\n\n/**\n * Antigravity wraps each streamGenerateContent SSE chunk under a `response`\n * key: `data: {\"response\": {\"candidates\": [...], \"usageMetadata\": {...}}}`.\n * Unwrap it so downstream sees the plain Gemini chunk. MITM-verified against\n * agy 1.0.4 on 2026-06-13.\n */\nfunction unwrapChunk(raw: unknown): GeminiStreamChunk {\n if (raw && typeof raw === 'object' && 'response' in raw) {\n const inner = (raw as { response?: unknown }).response\n if (inner && typeof inner === 'object') {\n return inner as GeminiStreamChunk\n }\n }\n return raw as GeminiStreamChunk\n}\n\nexport interface GeminiResponsePart {\n text?: string\n thought?: boolean\n thoughtSignature?: string\n functionCall?: { name?: string; args?: JsonObject; id?: string }\n}\n\nexport interface GeminiToolCallState {\n pendingThoughtSignature?: string\n}\n\nexport function convertGeminiToolCallPart(\n part: GeminiResponsePart,\n state: GeminiToolCallState,\n): ToolCall | undefined {\n // Antigravity emits a batch signature on a preceding empty thought part;\n // native replay attaches it to the first function call in that batch.\n if (part.thought && !part.text && part.thoughtSignature) {\n state.pendingThoughtSignature = part.thoughtSignature\n }\n\n if (!part.functionCall) return undefined\n\n const thoughtSignature =\n part.thoughtSignature ?? state.pendingThoughtSignature\n state.pendingThoughtSignature = undefined\n\n return {\n type: 'toolCall',\n id: part.functionCall.id ?? `call_${crypto.randomUUID()}`,\n name: part.functionCall.name ?? '',\n arguments: part.functionCall.args ?? {},\n ...(thoughtSignature ? { thoughtSignature } : {}),\n }\n}\n\nexport function updateUsage(\n model: Model<Api>,\n output: AssistantMessage,\n usage?: GeminiUsageMetadata,\n): void {\n if (!usage) return\n const cacheRead = usage.cachedContentTokenCount ?? output.usage.cacheRead\n // Antigravity reports promptTokenCount as the full (uncached + cached) prompt.\n const promptTotal =\n usage.promptTokenCount ?? output.usage.input + output.usage.cacheRead\n output.usage.input = Math.max(0, promptTotal - cacheRead)\n // candidatesTokenCount excludes thinking; thoughtsTokenCount is billed as\n // output too. totalTokenCount = prompt + candidates + thoughts.\n if (\n usage.candidatesTokenCount !== undefined ||\n usage.thoughtsTokenCount !== undefined\n ) {\n output.usage.output =\n (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0)\n }\n output.usage.cacheRead = cacheRead\n output.usage.totalTokens =\n output.usage.input +\n output.usage.output +\n output.usage.cacheRead +\n output.usage.cacheWrite\n calculateCost(model, output.usage)\n}\n\nexport async function* parseGeminiSse(\n response: Response,\n): AsyncGenerator<GeminiStreamChunk> {\n if (!response.body) return\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n const parseFrame = function* (frame: string): Generator<GeminiStreamChunk> {\n for (const line of frame.split('\\n')) {\n if (!line.startsWith('data:')) continue\n const data = line.slice(5).trim()\n if (!data || data === '[DONE]') continue\n try {\n yield unwrapChunk(JSON.parse(data))\n } catch {\n // Ignore malformed SSE frames.\n }\n }\n }\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n // Antigravity uses CRLF line endings (`\\r\\n\\r\\n` frame separators);\n // normalize so a single boundary check works for both LF and CRLF.\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, '\\n')\n let boundary = buffer.indexOf('\\n\\n')\n while (boundary !== -1) {\n const frame = buffer.slice(0, boundary)\n buffer = buffer.slice(boundary + 2)\n boundary = buffer.indexOf('\\n\\n')\n yield* parseFrame(frame)\n }\n }\n // Flush any trailing frame that did not end with a blank-line separator.\n if (buffer.trim()) {\n yield* parseFrame(buffer)\n }\n } finally {\n reader.releaseLock()\n }\n}\n\nfunction getRequestSessionKey(\n context: Context,\n options?: SimpleStreamOptions,\n): string {\n if (options?.sessionId) {\n return options.sessionId\n }\n // Pi 0.86+ gives every leading system message timestamp 0. A session key\n // based on that value would make unrelated conversations share one request-\n // metadata entry. Use the first non-system message's timestamp instead.\n const firstTimestamp = context.messages.find(\n (message) => message.role !== 'system',\n )?.timestamp\n return firstTimestamp !== undefined\n ? `message:${firstTimestamp}`\n : FALLBACK_SESSION_KEY\n}\n\nexport function finalizePiAntigravityRequest(\n request: Record<string, unknown>,\n wireModel: string,\n scope: AgyRequestScope,\n): string {\n if (Array.isArray(request.tools) && request.tools.length > 0) {\n request.toolConfig = { functionCallingConfig: { mode: 'VALIDATED' } }\n }\n\n const metadata = buildAgyAgentRequestMetadata(\n scope.session,\n request,\n wireModel,\n scope.timestamp,\n { stepCountMode: 'cli' },\n )\n request.labels = metadata.labels\n request.sessionId = metadata.sessionId\n orderAgyRequestPayloadInPlace(request)\n return metadata.requestId\n}\n\nexport function resolvePiAntigravityModel(\n model: Model<Api>,\n reasoning?: ThinkingLevel,\n) {\n const lower = model.id.toLowerCase()\n const supportsAgyTiers =\n model.reasoning &&\n (lower.includes('gemini-3') ||\n (lower.includes('claude') &&\n (lower.includes('thinking') || /claude-(opus|sonnet)-5-5/.test(lower))))\n\n if (!supportsAgyTiers || !reasoning) {\n return resolveModelForHeaderStyle(model.id, 'antigravity')\n }\n\n const tier =\n reasoning === 'minimal' ? 'low' : reasoning === 'xhigh' ? 'high' : reasoning\n const baseModel = model.id.replace(/-(minimal|low|medium|high|xhigh)$/i, '')\n return resolveModelForHeaderStyle(`${baseModel}-${tier}`, 'antigravity')\n}\n\n/** A request body built once per logical request, before any credential is chosen. */\ninterface PreparedAntigravityRequest {\n readonly wireModel: string\n readonly requestId: string\n readonly request: Record<string, unknown>\n}\n\n/**\n * The bearer and Antigravity project for one physical send. Both must come\n * from the same source: the local login, or one vault receipt.\n */\nexport interface AntigravitySendCredential {\n readonly accessToken: string\n readonly projectId: string\n}\n\nfunction prepareAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n sessionKey: string\n}): PreparedAntigravityRequest {\n const resolved = resolvePiAntigravityModel(\n options.model,\n options.streamOptions?.reasoning,\n )\n const wireModel = resolved.actualModel\n if (isRetiredAgyModel(options.model.id) || isRetiredAgyModel(wireModel)) {\n throw new Error(RETIRED_AGY_MODEL_MESSAGE)\n }\n\n const request: Record<string, unknown> = {\n ...buildGeminiRequest(options.context, {\n provider: options.model.provider,\n model: options.model.id,\n }),\n }\n const generationConfig: Record<string, unknown> = {}\n\n if (resolved.thinkingLevel) {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingLevel: resolved.thinkingLevel,\n }\n } else if (typeof resolved.thinkingBudget === 'number') {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingBudget: resolved.thinkingBudget,\n }\n }\n\n const maxTokens = options.streamOptions?.maxTokens ?? options.model.maxTokens\n if (typeof maxTokens === 'number') {\n generationConfig.maxOutputTokens = maxTokens\n }\n applyAgyNativeGenerationConfig(wireModel, generationConfig)\n\n if (Object.keys(generationConfig).length > 0) {\n request.generationConfig = generationConfig\n }\n\n const requestScope = requestSessions.beginRequest(options.sessionKey)\n const requestId = finalizePiAntigravityRequest(\n request,\n wireModel,\n requestScope,\n )\n return { wireModel, requestId, request }\n}\n\n/** One physical send of a prepared request with one credential. */\nfunction dispatchAntigravityRequest(\n prepared: PreparedAntigravityRequest,\n credential: AntigravitySendCredential,\n signal: AbortSignal | null,\n): Promise<Response> {\n const envelope = {\n project: credential.projectId,\n requestId: prepared.requestId,\n request: prepared.request,\n model: prepared.wireModel,\n userAgent: 'antigravity',\n requestType: 'agent',\n }\n\n const url = `${ANTIGRAVITY_ENDPOINT}/v1internal:${STREAM_ACTION}?alt=sse`\n\n return fetchWithAgyCliTransport(\n url,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${credential.accessToken}`,\n 'Content-Type': 'application/json',\n 'User-Agent': buildAntigravityHarnessUserAgent(),\n 'Accept-Encoding': 'gzip',\n },\n body: JSON.stringify(envelope),\n },\n { signal },\n )\n}\n\n/** Local mode only; custody sends never reach this path. */\nasync function sendAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n accessToken: string\n sessionKey: string\n signal?: AbortSignal\n assertAdmission?: () => Promise<void>\n}): Promise<Response> {\n if (isRetiredAgyModel(options.model.id)) {\n throw new Error(RETIRED_AGY_MODEL_MESSAGE)\n }\n // Pi passes only the access token; the packed refresh\n // `refreshToken|projectId|managedProjectId` saved at getApiKey supplies\n // the managed project without a loadCodeAssist call per turn.\n const packedRefresh = getPackedRefresh(options.accessToken) ?? ''\n const projectContext = await ensureProjectContext({\n type: 'oauth',\n refresh: packedRefresh,\n access: options.accessToken,\n expires: Date.now() + 60_000,\n })\n\n const prepared = prepareAntigravityRequest(options)\n await options.assertAdmission?.()\n return dispatchAntigravityRequest(\n prepared,\n {\n accessToken: options.accessToken,\n projectId: projectContext.effectiveProjectId,\n },\n options.signal ?? options.streamOptions?.signal ?? null,\n )\n}\n\n/**\n * Vault (custody) mode: sends a prepared request through the vault. `send`\n * must call `dispatch` once per physical send, each time with the token and\n * project of a fresh vault receipt, and returns the response that was\n * finally served.\n */\nexport type AntigravityVaultSend = (\n dispatch: (\n credential: AntigravitySendCredential,\n signal?: AbortSignal,\n ) => Promise<Response>,\n signal: AbortSignal,\n) => Promise<Response>\n\ntype OpenAntigravityResponse = (\n sessionKey: string,\n signal: AbortSignal,\n selectedCredentials: Set<string>,\n) => Promise<Response>\n\nexport function streamCortexKitAntigravity(\n model: Model<Api>,\n context: Context,\n options?: SimpleStreamOptions,\n assertAdmission?: () => Promise<void>,\n): AssistantMessageEventStream {\n return runAntigravityStream(\n model,\n context,\n options,\n async (sessionKey, signal) => {\n await assertAdmission?.()\n const accessToken = options?.apiKey ?? ''\n if (!accessToken)\n throw new Error('Missing Antigravity OAuth access token')\n return sendAntigravityRequest({\n model,\n context,\n streamOptions: options,\n accessToken,\n sessionKey,\n signal,\n assertAdmission,\n })\n },\n )\n}\n\n/**\n * In vault mode, Pi's Google auth slot contains a fixed API-key marker,\n * not a real credential. Refuse any other resolved key so a stale local\n * login cannot enter this stream. Each physical request obtains its bearer\n * and project from the vault; local credentials and project caches are unused.\n */\nexport function createCortexKitAntigravityVaultStream(\n send: AntigravityVaultSend,\n placeholderKey: string,\n) {\n return (\n model: Model<Api>,\n context: Context,\n options?: SimpleStreamOptions,\n ): AssistantMessageEventStream =>\n runAntigravityStream(\n model,\n context,\n options,\n (sessionKey, signal, selectedCredentials) => {\n if (options?.apiKey !== placeholderKey)\n throw new Error(\n 'The native Google credential slot is not synchronized for vault mode. No request was sent.',\n )\n const prepared = prepareAntigravityRequest({\n model,\n context,\n streamOptions: options,\n sessionKey,\n })\n return send(async (credential, sendSignal) => {\n selectedCredentials.add(credential.accessToken)\n try {\n return await dispatchAntigravityRequest(\n prepared,\n credential,\n sendSignal ?? signal,\n )\n } catch (error) {\n throw redactCredentialError(error, [...selectedCredentials])\n }\n }, signal)\n },\n )\n}\n\nfunction runAntigravityStream(\n model: Model<Api>,\n context: Context,\n options: SimpleStreamOptions | undefined,\n open: OpenAntigravityResponse,\n): AssistantMessageEventStream {\n const stream = createAssistantMessageEventStream()\n\n void (async () => {\n const output = createOutput(model)\n const selectedCredentials = new Set<string>(\n options?.apiKey ? [options.apiKey] : [],\n )\n stream.push({ type: 'start', partial: output })\n let response: Response | undefined\n let requestAbort: AbortController | undefined\n let chunkIterator: AsyncIterator<GeminiStreamChunk> | undefined\n let detachCaller = () => {}\n\n try {\n const sessionKey = getRequestSessionKey(context, options)\n requestAbort = new AbortController()\n detachCaller = forwardAbort(options?.signal, requestAbort)\n response = await open(\n sessionKey,\n requestAbort.signal,\n selectedCredentials,\n )\n\n if (!response.ok) {\n throw new Error(\n `Antigravity request failed: HTTP ${response.status} ${await response.text()}`,\n )\n }\n\n const content = output.content as Array<\n TextContent | ThinkingContent | ToolCall\n >\n const toolCallState: GeminiToolCallState = {}\n let textIndex = -1\n let thinkingIndex = -1\n let terminalSeen = false\n\n const closeText = () => {\n if (textIndex === -1) return\n const block = content[textIndex]\n if (block?.type === 'text') {\n stream.push({\n type: 'text_end',\n contentIndex: textIndex,\n content: block.text,\n partial: output,\n })\n }\n textIndex = -1\n }\n\n const closeThinking = () => {\n if (thinkingIndex === -1) return\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n stream.push({\n type: 'thinking_end',\n contentIndex: thinkingIndex,\n content: block.thinking,\n partial: output,\n })\n }\n thinkingIndex = -1\n }\n\n chunkIterator = parseGeminiSse(response)[Symbol.asyncIterator]()\n let terminalFinishReason: string | undefined\n while (true) {\n const next = terminalSeen\n ? await nextWithTimeout(\n chunkIterator,\n TRAILING_USAGE_TIMEOUT_MS,\n () => requestAbort?.abort(),\n )\n : await chunkIterator.next()\n if (!next) break\n if (next.done) break\n\n const chunk = next.value\n const embeddedFailure = describeEmbeddedStreamFailure(chunk)\n if (embeddedFailure) throw new Error(embeddedFailure)\n updateUsage(model, output, chunk.usageMetadata)\n\n if (terminalSeen) {\n if (chunk.usageMetadata) break\n continue\n }\n\n const candidate = chunk.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n if (\n !part.thought &&\n !part.functionCall &&\n !part.text &&\n part.thoughtSignature\n ) {\n const block = textIndex === -1 ? undefined : content[textIndex]\n if (block?.type === 'text') {\n block.textSignature = part.thoughtSignature\n } else {\n toolCallState.pendingThoughtSignature = part.thoughtSignature\n }\n continue\n }\n\n const toolCall = convertGeminiToolCallPart(part, toolCallState)\n if (toolCall) {\n closeText()\n closeThinking()\n content.push(toolCall)\n const idx = content.length - 1\n stream.push({\n type: 'toolcall_start',\n contentIndex: idx,\n partial: output,\n })\n stream.push({\n type: 'toolcall_end',\n contentIndex: idx,\n toolCall,\n partial: output,\n })\n output.stopReason = 'toolUse'\n continue\n }\n\n if (part.thought) {\n if (typeof part.text !== 'string' || part.text.length === 0)\n continue\n closeText()\n if (thinkingIndex === -1) {\n content.push({\n type: 'thinking',\n thinking: '',\n ...(part.thoughtSignature\n ? { thinkingSignature: part.thoughtSignature }\n : {}),\n })\n thinkingIndex = content.length - 1\n stream.push({\n type: 'thinking_start',\n contentIndex: thinkingIndex,\n partial: output,\n })\n }\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n block.thinking += part.text\n if (part.thoughtSignature)\n block.thinkingSignature = part.thoughtSignature\n stream.push({\n type: 'thinking_delta',\n contentIndex: thinkingIndex,\n delta: part.text,\n partial: output,\n })\n }\n continue\n }\n\n if (typeof part.text === 'string' && part.text.length > 0) {\n closeThinking()\n if (textIndex === -1) {\n const textSignature =\n part.thoughtSignature ?? toolCallState.pendingThoughtSignature\n toolCallState.pendingThoughtSignature = undefined\n content.push({\n type: 'text',\n text: '',\n ...(textSignature ? { textSignature } : {}),\n })\n textIndex = content.length - 1\n stream.push({\n type: 'text_start',\n contentIndex: textIndex,\n partial: output,\n })\n }\n const block = content[textIndex]\n if (block?.type === 'text') {\n block.text += part.text\n if (part.thoughtSignature)\n block.textSignature = part.thoughtSignature\n stream.push({\n type: 'text_delta',\n contentIndex: textIndex,\n delta: part.text,\n partial: output,\n })\n }\n }\n }\n\n if (candidate?.finishReason) {\n closeText()\n closeThinking()\n if (output.stopReason !== 'toolUse') {\n output.stopReason = mapFinishReason(candidate.finishReason)\n }\n terminalSeen = true\n terminalFinishReason = candidate.finishReason\n const needsTrailingUsage =\n model.id.toLowerCase().includes('gpt-oss') && !chunk.usageMetadata\n if (!needsTrailingUsage) break\n }\n }\n\n if (terminalSeen) {\n try {\n await chunkIterator.return?.(undefined)\n } catch (error) {\n if (!requestAbort.signal.aborted) throw error\n }\n await response.body?.cancel().catch(() => {})\n }\n\n if (options?.signal?.aborted) throw new Error('Request was aborted')\n if (!terminalSeen) {\n throw new Error(\n 'Antigravity stream ended without a terminal candidate response',\n )\n }\n if (content.length === 0) {\n throw new Error(\n `Antigravity returned an empty response${terminalFinishReason ? ` (${terminalFinishReason})` : ''}`,\n )\n }\n\n stream.push({\n type: 'done',\n reason: output.stopReason as 'stop' | 'length' | 'toolUse',\n message: output,\n })\n if (output.stopReason === 'stop' || output.stopReason === 'length') {\n requestSessions.completeExecution(sessionKey)\n }\n stream.end()\n } catch (error) {\n requestAbort?.abort()\n await chunkIterator?.return?.(undefined).catch(() => {})\n await response?.body?.cancel().catch(() => {})\n output.stopReason = options?.signal?.aborted ? 'aborted' : 'error'\n output.errorMessage = redactCredentialText(\n error instanceof Error ? error.message : String(error),\n [...selectedCredentials],\n )\n stream.push({ type: 'error', reason: output.stopReason, error: output })\n stream.end()\n } finally {\n detachCaller()\n }\n })()\n\n return stream\n}\n", "import { toGeminiSchema } from '@cortexkit/antigravity-auth-core'\nimport type {\n AssistantMessage,\n Context,\n ImageContent,\n Message,\n TextContent,\n Tool,\n ToolResultMessage,\n} from '@earendil-works/pi-ai'\n// Namespace import so the transcript helpers can be feature-detected: a named\n// import of an export that an older installed pi-ai lacks fails at module link\n// time and would stop the extension from loading at all.\nimport * as piAi from '@earendil-works/pi-ai'\n\n/** Gemini `contents` part shapes. */\ntype GeminiPart =\n | { text: string; thought?: boolean; thoughtSignature?: string }\n | { inlineData: { mimeType: string; data: string } }\n | {\n functionCall: { name: string; args: Record<string, unknown>; id: string }\n thoughtSignature?: string\n }\n | {\n functionResponse: {\n name: string\n response: Record<string, unknown>\n id: string\n }\n }\n\ninterface GeminiContent {\n role: 'user' | 'model'\n parts: GeminiPart[]\n}\n\ninterface GeminiTool {\n functionDeclarations: Array<{\n name: string\n description: string\n parameters?: unknown\n }>\n}\n\nexport interface GeminiRequest {\n contents: GeminiContent[]\n tools?: GeminiTool[]\n systemInstruction?: { parts: GeminiPart[] }\n}\n\nfunction sanitize(text: string): string {\n return text.replace(/[\\uD800-\\uDFFF]/gu, '\\uFFFD')\n}\n\nfunction convertUserParts(\n content: Array<TextContent | ImageContent>,\n): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const item of content) {\n if (item.type === 'text') {\n if (item.text) parts.push({ text: sanitize(item.text) })\n } else if (item.type === 'image' && item.data) {\n parts.push({ inlineData: { mimeType: item.mimeType, data: item.data } })\n }\n }\n return parts\n}\n\nfunction convertAssistantParts(\n message: AssistantMessage,\n preserveSignedHistory: boolean,\n): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const block of message.content) {\n if (block.type === 'thinking') {\n if (preserveSignedHistory && block.thinking) {\n parts.push({\n text: sanitize(block.thinking),\n thought: true,\n ...(block.thinkingSignature\n ? { thoughtSignature: block.thinkingSignature }\n : {}),\n })\n }\n } else if (block.type === 'text' && block.text.trim()) {\n parts.push({\n text: sanitize(block.text),\n ...(preserveSignedHistory && block.textSignature\n ? { thoughtSignature: block.textSignature }\n : {}),\n })\n } else if (block.type === 'toolCall') {\n parts.push({\n functionCall: {\n name: block.name,\n args: (block.arguments ?? {}) as Record<string, unknown>,\n id: block.id,\n },\n ...(preserveSignedHistory && block.thoughtSignature\n ? { thoughtSignature: block.thoughtSignature }\n : {}),\n })\n }\n }\n return parts\n}\n\nfunction toolResultResponse(\n message: ToolResultMessage,\n): Record<string, unknown> {\n const text = message.content\n .filter((item): item is TextContent => item.type === 'text')\n .map((item) => item.text)\n .join('\\n')\n if (message.isError) {\n return { error: text || 'Error' }\n }\n return { output: text }\n}\n\nexport interface BuildGeminiRequestOptions {\n provider?: string\n model?: string\n}\n\nfunction isSameTargetModel(\n message: AssistantMessage,\n options: BuildGeminiRequestOptions | undefined,\n): boolean {\n if (!options?.provider || !options.model) return true\n return (\n message.provider === options.provider && message.model === options.model\n )\n}\n\nfunction convertMessages(\n messages: Message[],\n options?: BuildGeminiRequestOptions,\n): GeminiContent[] {\n const contents: GeminiContent[] = []\n const callMatchesTarget = new Map<string, boolean>()\n\n for (const message of messages) {\n if (message?.role !== 'assistant') continue\n const matchesTarget = isSameTargetModel(message, options)\n for (const block of message.content) {\n if (block.type === 'toolCall') {\n callMatchesTarget.set(block.id, matchesTarget)\n }\n }\n }\n\n for (const message of messages) {\n if (!message) continue\n\n // System messages carry the prompt and tool state, which\n // resolveInstructionState replays into systemInstruction and tools.\n if (message.role === 'system') continue\n\n if (message.role === 'user') {\n const parts =\n typeof message.content === 'string'\n ? message.content.trim()\n ? [{ text: sanitize(message.content) }]\n : []\n : convertUserParts(\n message.content as Array<TextContent | ImageContent>,\n )\n if (parts.length) contents.push({ role: 'user', parts })\n continue\n }\n\n if (message.role === 'assistant') {\n const parts = convertAssistantParts(\n message,\n isSameTargetModel(message, options),\n )\n if (parts.length) contents.push({ role: 'model', parts })\n continue\n }\n\n if (message.role === 'toolResult') {\n const role =\n callMatchesTarget.get(message.toolCallId) === true ? 'model' : 'user'\n const part: GeminiPart = {\n functionResponse: {\n name: message.toolName,\n response: toolResultResponse(message),\n id: message.toolCallId,\n },\n }\n // Gemini groups consecutive function responses into one user turn.\n const last = contents[contents.length - 1]\n if (\n last &&\n last.role === role &&\n last.parts.every((p) => 'functionResponse' in p)\n ) {\n last.parts.push(part)\n } else {\n contents.push({ role, parts: [part] })\n }\n }\n }\n\n return contents\n}\n\nfunction convertTools(\n tools: Tool[] | undefined,\n model?: string,\n): GeminiTool[] | undefined {\n if (!tools?.length) return undefined\n return [\n {\n // Match the agy wire format (MITM-verified): field name is `parameters`\n // (not `parametersJsonSchema`) and schemas are sanitized to Gemini shape\n // (UPPERCASE types, unsupported keywords stripped) via core's toGeminiSchema.\n functionDeclarations: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: toGeminiSchema(tool.parameters, {\n moveNumericConstraintsToDescription: model\n ?.replace(/^antigravity-/, '')\n .startsWith('gpt-oss-'),\n }),\n })),\n },\n ]\n}\n\ninterface InstructionState {\n systemPrompt: string\n tools: Tool[]\n}\n\n/**\n * Resolve the system prompt and tool set the request must carry.\n *\n * Pi 0.86+ hands providers a transcript whose system messages hold the prompt\n * and tools: the leading one declares them and later ones append text, patch\n * named sections, and add or remove tools. When the transcript has any system\n * message it is the only authority, replayed with pi-ai's own helpers, so a\n * prompt or tool set emptied by later system messages stays empty even if\n * flat `systemPrompt`/`tools` fields are also present. Older Pi runtimes pass\n * a flat `Context` with no system messages, which is read as-is.\n */\nfunction resolveInstructionState(context: Context): InstructionState {\n if (!context.messages.some((message) => message?.role === 'system')) {\n return {\n systemPrompt: context.systemPrompt ?? '',\n tools: context.tools ?? [],\n }\n }\n\n if (\n typeof piAi.getCurrentSystemPrompt !== 'function' ||\n typeof piAi.getCurrentTools !== 'function'\n ) {\n // Dropping the system messages would silently send a request with no\n // prompt and no tools, so refuse instead.\n throw new Error(\n 'Pi transcript contains system messages but the installed @earendil-works/pi-ai does not export getCurrentSystemPrompt/getCurrentTools (requires >= 0.86)',\n )\n }\n\n return {\n systemPrompt: piAi.getCurrentSystemPrompt(context.messages),\n tools: piAi.getCurrentTools(context.messages),\n }\n}\n\n/**\n * Convert a pi request context into a Gemini `generateContent` request body\n * (the inner `request` object of the Antigravity envelope). Accepts both the\n * transcript form Pi 0.86+ passes to providers and the flat `Context` of\n * older runtimes.\n */\nexport function buildGeminiRequest(\n context: Context,\n options?: BuildGeminiRequestOptions,\n): GeminiRequest {\n const request: GeminiRequest = {\n contents: convertMessages(context.messages, options),\n }\n\n const { systemPrompt, tools } = resolveInstructionState(context)\n\n const geminiTools = convertTools(tools, options?.model)\n if (geminiTools) request.tools = geminiTools\n\n if (systemPrompt.trim()) {\n request.systemInstruction = {\n parts: [{ text: sanitize(systemPrompt) }],\n }\n }\n\n return request\n}\n", "/**\n * Pi's custody request path. Each physical send takes its bearer and\n * Antigravity project from one fresh vault receipt, so a revoked account or\n * a moved project applies on the next send and a 401 is reported against the\n * exact record version that was served. Nothing is cached or refreshed\n * locally. Each send checks the vault mode file. Account discovery and\n * changes use the vault source's enrollment checks, without reading Pi's\n * saved Google login.\n */\n\nimport { existsSync } from 'node:fs'\n\nimport {\n type AntigravityVaultAccountSource,\n type CommonAuthClaustrumModule,\n type CommonAuthCommandsModule,\n type CommonAuthPiSlotModule,\n createAntigravityVaultAccountSource,\n enrollmentAuthority,\n loadCommonAuthClaustrum,\n type VaultRouteRef,\n} from '@cortexkit/antigravity-auth-core'\nimport type {\n ClaustrumEnrollmentConnection,\n ClaustrumScopedClient,\n} from '@cortexkit/antigravity-auth-core/common-auth/claustrum'\n\nimport {\n getPiAntigravityVaultDir,\n getPiAntigravityVaultModeFile,\n getPiAntigravityVaultRosterFile,\n} from './paths.ts'\nimport type { AntigravityVaultSend } from './stream.ts'\nimport {\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n PI_ANTIGRAVITY_VAULT_HOST,\n type PiVaultAccountChoice,\n type PiVaultAccountsPort,\n type PiVaultModeRead,\n type PiVaultModeRecord,\n PiVaultSetup,\n readPiVaultMode,\n} from './vault-setup.ts'\n\n/** The shared vault account source operations Pi's request path and setup use. */\nexport type PiVaultAccountSource = Pick<\n AntigravityVaultAccountSource,\n 'refresh' | 'routes' | 'send' | 'decline' | 'accept'\n>\n\ntype PiVaultRouteRef = VaultRouteRef\n\nexport class PiVaultSendError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PiVaultSendError'\n }\n}\n\nexport interface PiVaultRequestPathOptions {\n /** Read this host's vault enrollment and account-source choice before each operation; never reuse an earlier request's state. */\n readMode: () => PiVaultModeRead | Promise<PiVaultModeRead>\n /** The shared vault account source, created once on first use. */\n source: () => Promise<PiVaultAccountSource>\n}\n\n/** Require current vault-mode settings before opening the account source; refuse local or unreadable settings. */\nfunction requireCustody(read: PiVaultModeRead): PiVaultModeRecord {\n if (!read.ok)\n throw new PiVaultSendError(\n `Antigravity vault mode is unclear (${read.reason}). Choose a mode in the Vault section of the Antigravity menu.`,\n )\n if (read.record.mode !== 'custody')\n throw new PiVaultSendError(\n 'Antigravity is not served from the vault. Switch in the Vault section of the Antigravity menu.',\n )\n return read.record\n}\n\nfunction selectRoute(\n routes: readonly PiVaultRouteRef[],\n routeId: string | undefined,\n): PiVaultRouteRef {\n if (routeId !== undefined) {\n const selected = routes.find((route) => route.routeId === routeId)\n if (!selected)\n throw new PiVaultSendError(\n 'The chosen vault account is no longer available (declined, removed or changed). Choose another in the Vault section of the Antigravity menu.',\n )\n return selected\n }\n const [only, ...rest] = routes\n if (!only)\n throw new PiVaultSendError(\n 'The vault serves Pi no Antigravity accounts yet.',\n )\n if (rest.length > 0)\n throw new PiVaultSendError(\n 'The vault serves Pi several Antigravity accounts. Choose one in the Vault section of the Antigravity menu.',\n )\n return only\n}\n\n/** Custody checks that run before discovery, a roster change or a send. */\nasync function openCustody(\n options: PiVaultRequestPathOptions,\n): Promise<{ record: PiVaultModeRecord; source: PiVaultAccountSource }> {\n const record = requireCustody(await options.readMode())\n const source = await options.source()\n return { record, source }\n}\n\n/** The send function the custody stream uses for every model request. */\nexport function createPiVaultSend(\n options: PiVaultRequestPathOptions,\n): AntigravityVaultSend {\n return async (dispatch, signal) => {\n const { record, source } = await openCustody(options)\n signal.throwIfAborted()\n let routes = source.routes()\n if (routes.length === 0) {\n // Load the vault roster before selecting an account for this request.\n await source.refresh()\n signal.throwIfAborted()\n routes = source.routes()\n }\n // Capture the route before any further await, so the send is bound to\n // the account the roster named now, not to whatever later sits there.\n const ref = selectRoute(routes, record.routeId)\n return source.send(ref, dispatch, { site: 'model', signal })\n }\n}\n\n/** Vault accounts for the setup command, with declined ones marked. */\nexport function createPiVaultAccountsPort(\n options: PiVaultRequestPathOptions,\n): PiVaultAccountsPort {\n // Kept from the last listing so decline/accept act on the account the user\n // picked, never on a route id that now names another account.\n let lastRows = new Map<string, PiVaultRouteRef>()\n\n const refFor = (routeId: string): PiVaultRouteRef => {\n const ref = lastRows.get(routeId)\n if (!ref)\n throw new PiVaultSendError(\n 'That vault account is no longer listed. Open the Vault section again.',\n )\n return ref\n }\n\n return {\n list: async () => {\n const { source } = await openCustody(options)\n const roster = await source.refresh()\n const rows = new Map<string, PiVaultRouteRef>()\n const choices: PiVaultAccountChoice[] = []\n for (const row of roster?.rows ?? []) {\n if (!row.accountIdentity) continue\n const ref: PiVaultRouteRef = {\n routeId: row.routeId,\n credentialId: row.credentialId,\n accountIdentity: row.accountIdentity,\n label: row.label,\n ...(row.email !== undefined && { email: row.email }),\n }\n rows.set(row.routeId, ref)\n const declined = (roster?.declined ?? []).some(\n (entry) =>\n entry.credentialId === row.credentialId &&\n (entry.accountIdentity === undefined ||\n entry.accountIdentity === row.accountIdentity),\n )\n choices.push({\n routeId: row.routeId,\n label: row.label,\n ...(row.email !== undefined && { email: row.email }),\n declined,\n })\n }\n lastRows = rows\n return choices\n },\n decline: async (routeId) => {\n const { source } = await openCustody(options)\n await source.decline(refFor(routeId))\n },\n accept: async (routeId) => {\n const { source } = await openCustody(options)\n await source.accept(refFor(routeId))\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Production composition\n// ---------------------------------------------------------------------------\n\n/**\n * I/O seams of the vault composition. Pi's default entry passes none: the\n * vault client connects through the connection file Claustrum publishes,\n * Pi's auth slot is read from Pi's auth.json, and files live under Pi's\n * vault directory. Tests replace only the client transport and file paths.\n */\nexport interface PiVaultSeams {\n connect?: () => Promise<ClaustrumScopedClient>\n connectEnrollment?: () => Promise<ClaustrumEnrollmentConnection>\n readHostSlot?: () => unknown\n nativeAuthPath?: string\n nativeStashPath?: string\n loadPiSlot?: () => Promise<CommonAuthPiSlotModule>\n vaultDir?: string\n modeFile?: string\n rosterFile?: string\n loadClaustrum?: () => Promise<CommonAuthClaustrumModule>\n /** Commands library loader for the menu (tests capture the renderer call). */\n loadCommands?: () => Promise<CommonAuthCommandsModule>\n}\n\nexport interface PiVaultRuntime {\n readMode(): PiVaultModeRead\n readonly requestPath: PiVaultRequestPathOptions\n setup(): Promise<PiVaultSetup>\n}\n\nasync function claustrumConnectionFile(): Promise<string> {\n const { resolveClaustrumConnectionPath } = await import(\n '@cortexkit/claustrum-client'\n )\n return resolveClaustrumConnectionPath()\n}\n\nfunction memoize<T>(load: () => Promise<T>): () => Promise<T> {\n let pending: Promise<T> | undefined\n return () => {\n pending ??= load().catch((error: unknown) => {\n pending = undefined\n throw error\n })\n return pending\n }\n}\n\n/**\n * Build Pi's vault composition. Nothing is loaded or connected here; the\n * vault library and the shared account source are created on the first\n * custody send or setup action.\n */\nexport function createPiVaultRuntime(\n readHostSlot: () => unknown,\n seams: PiVaultSeams = {},\n onModeChanged?: (record: PiVaultModeRecord) => void | Promise<void>,\n): PiVaultRuntime {\n const vaultDir = seams.vaultDir ?? getPiAntigravityVaultDir()\n const modeFile = seams.modeFile ?? getPiAntigravityVaultModeFile()\n const rosterFile = seams.rosterFile ?? getPiAntigravityVaultRosterFile()\n const loadClaustrum = seams.loadClaustrum ?? loadCommonAuthClaustrum\n const readMode = () => readPiVaultMode(modeFile)\n\n const source = memoize(async (): Promise<PiVaultAccountSource> => {\n const claustrum = await loadClaustrum()\n const { tokenPath } = claustrum.hostEnrollmentPaths({\n stateDir: vaultDir,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n })\n return createAntigravityVaultAccountSource({\n claustrum,\n host: PI_ANTIGRAVITY_VAULT_HOST,\n rosterPath: rosterFile,\n tokenPath,\n connect:\n seams.connect ??\n (async () =>\n claustrum.connectClaustrumScopedClient({\n connectionFile: await claustrumConnectionFile(),\n })),\n // The vault serves this host only once setup has stored an approved\n // enrollment token; Pi's own send path also requires custody mode.\n isCustodyActive: () => existsSync(tokenPath),\n // Pi reads the HTTP status of each send itself.\n reporterSource: 'direct',\n })\n })\n\n const setup = memoize(async () => {\n const claustrum = await loadClaustrum()\n return new PiVaultSetup({\n claustrum,\n stateDir: vaultDir,\n modeFile,\n readHostSlot,\n ...(onModeChanged && { onModeChanged }),\n connectEnrollment:\n seams.connectEnrollment ??\n (async () =>\n claustrum.connectClaustrumEnrollmentClient({\n connectionFile: await claustrumConnectionFile(),\n })),\n })\n })\n\n return {\n readMode,\n setup,\n requestPath: {\n readMode: async () => {\n const settings = await setup()\n const status = await settings.sourceStatus()\n const authority = await enrollmentAuthority(\n settings.paths,\n PI_ANTIGRAVITY_ENROLLMENT_NAME,\n )\n if (authority === 'local' && status.mode === 'custody')\n throw new PiVaultSendError(\n 'Vault enrollment is not active. No request was sent.',\n )\n if (status.mode === 'unreadable')\n throw new PiVaultSendError(\n 'Vault enrollment or source settings cannot be read.',\n )\n return {\n ok: true,\n record: {\n version: 1,\n mode: status.mode,\n ...(status.selectedRouteId\n ? { routeId: status.selectedRouteId }\n : {}),\n },\n }\n },\n source,\n },\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["join", "ANTIGRAVITY_PROVIDER_ID", "enrollmentAuthority", "reason", "message", "enrollmentAuthority", "enrollmentAuthority", "ANTIGRAVITY_PROVIDER_ID", "enrollmentAuthority", "join"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/pi-antigravity-auth",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Google Antigravity OAuth extension for pi - access Gemini and Claude models using Google credentials",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"prepublishOnly": "bun run build"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@cortexkit/antigravity-auth-core": "3.0.
|
|
46
|
+
"@cortexkit/antigravity-auth-core": "3.0.3",
|
|
47
47
|
"@cortexkit/claustrum-client": "0.6.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|