Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,18 @@ presentation comes from a Scient hook (its import and its call), so a sign-in st
as starting from the click, and a failed sign-in or setup takes the error status dot. See
[provider lifecycle](docs/internals/provider-lifecycle.md#opening-sign-in-pages).

One marked seam in `packages/provider-acp/src/server/AcpSessionRuntime.ts` keeps an agent that owns
its process tree attached on Windows: `ownDetachedProcessGroup` spawns detached only off Windows,
where `taskkill /T` already stops the tree. A detached agent has no console, so every console
program it starts opens a visible window; Antigravity's own inner process is one. This is an
upstream bug (T3's Grok uses the same path) worth proposing. In Scient's retained
`AntigravityInstallation.ts`, a runtime check that runs out of time reports that instead of the
install's catch-all disk-space advice.
The install check, model refresh (`AntigravityDriver.ts`) and sign-out (`AntigravityAuth.ts`)
allow 5 minutes instead of T3's 90 seconds, each in a marked line: the
official Windows agent unpacks about 7,300 files (320 MiB) into a fresh folder on every start, which
took about 35 s on a development machine and can exceed 90 s on slower disks.

Antigravity reasoning presentation is a narrow client-side divergence. The shared
`packages/client-runtime/src/antigravityModelPresentation.ts` groups recognized
Google Gemini effort variants for the existing model and reasoning controls.
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/provider/AntigravityAuth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ it.layer(NodeServices.layer)("AntigravityAuth", (it) => {
.logout(Effect.void)
.pipe(Effect.exit, Effect.forkScoped);
yield* Deferred.await(entered);
yield* TestClock.adjust("90 seconds");
yield* TestClock.adjust("5 minutes");
assert.isTrue(Exit.isFailure(yield* Fiber.join(logout)));
yield* Deferred.await(harness.closed);
assert.notInclude(harness.events, "logout");
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/provider/AntigravityAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,9 @@ export const makeAntigravityAuth = Effect.fn("makeAntigravityAuth")(function* <
}).pipe(
Effect.scoped,
Effect.timeoutOrElse({
duration: "90 seconds",
// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes.
duration: "5 minutes",
// SCIENT-FORK:END
orElse: () => Effect.fail(setupError("logout", "Antigravity sign-out timed out.")),
}),
),
Expand Down
24 changes: 22 additions & 2 deletions apps/server/src/provider/AntigravityInstallation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,15 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => {
cancel: true,
valid: false,
},
{
name: "a Windows ARM verification that runs out of time with locked child processes",
platform: "win32" as const,
arch: "arm64" as const,
agentName: "antigravity-acp",
version: "fixture-new",
timeout: true,
valid: false,
},
].flatMap((testCase) => {
const cleanupErrorTags =
testCase.platform === "win32"
Expand Down Expand Up @@ -622,7 +631,9 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => {
Effect.asVoid,
);
if (!helper) {
expect(command.options.detached).toBe(true);
// The real host decides, not the simulated platform: Windows owns the
// tree with taskkill, and detaching there would show a console.
expect(command.options.detached).toBe(hostPlatform !== "win32");
stopNative = terminate;
}
yield* Effect.addFinalizer(() =>
Expand Down Expand Up @@ -652,7 +663,7 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => {
Effect.orDie,
);
methods.push(request.method);
if (testCase.cancel) {
if (testCase.cancel || testCase.timeout) {
yield* Deferred.succeed(initializationStarted, undefined);
return;
}
Expand Down Expand Up @@ -740,6 +751,10 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => {
Effect.forkChild,
)
: undefined;
if (testCase.timeout) {
yield* Deferred.await(initializationStarted);
yield* TestClock.adjust("5 minutes");
}
if (platform === "win32") {
yield* Effect.raceFirst(
Deferred.await(cleanupRetryStarted).pipe(Effect.andThen(TestClock.adjust("100 millis"))),
Expand All @@ -750,6 +765,11 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => {
expect((yield* terminalState(installation)).phase).toBe(
testCase.cancel ? "cancelled" : testCase.valid ? "succeeded" : "failed",
);
if (testCase.timeout) {
expect((yield* terminalState(installation)).message).toBe(
"Antigravity didn't finish starting within 5 minutes while Scient was checking it. Starting it can take a while on some computers. Try again.",
);
}
yield* Deferred.await(stagingReleased);
expect(methods).toEqual(["initialize"]);
expect(closedRuntimes).toBe(1);
Expand Down
25 changes: 23 additions & 2 deletions apps/server/src/provider/AntigravityInstallation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ import {

const DRIVER = ProviderDriverKind.make("antigravity");
const DOWNLOAD_TIMEOUT = "45 minutes";
const VALIDATION_TIMEOUT = "90 seconds";
// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes.
const VALIDATION_TIMEOUT = "5 minutes";
// SCIENT-FORK:END
const FREE_SPACE_MARGIN = 256 * 1024 * 1024;
const RECORD_MAX_BYTES = 8 * 1024;
const RELEASE_RECORD = ".install-complete.json";
Expand Down Expand Up @@ -151,6 +153,20 @@ const installationError = (operation: string, detail: string, cause?: unknown) =
const wrapFailure = (operation: string, detail: string) => (cause: unknown) =>
isInstallationError(cause) ? cause : installationError(operation, detail, cause);

// SCIENT-FORK:START — a check that runs out of time says so, instead of the
// install's catch-all advice to check disk space.
const validationTimeout = Effect.timeoutOrElse({
duration: VALIDATION_TIMEOUT,
orElse: () =>
Effect.fail(
installationError(
"verify",
`Antigravity didn't finish starting within ${VALIDATION_TIMEOUT} while Scient was checking it. Starting it can take a while on some computers. Try again.`,
),
),
});
// SCIENT-FORK:END

function executableNames(platform: NodeJS.Platform) {
return platform === "win32"
? { executable: "agy_acp_server.exe", harness: "localharness_external.exe" }
Expand Down Expand Up @@ -712,7 +728,12 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma
managedVersionDirectory: pairDirectory,
},
asset.version,
).pipe(Effect.scoped, Effect.timeout(VALIDATION_TIMEOUT));
).pipe(
Effect.scoped,
// SCIENT-FORK:START
validationTimeout,
// SCIENT-FORK:END
);
const record: InstalledRelease = {
releaseId: asset.sha256,
version: asset.version,
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/provider/Drivers/AntigravityDriver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ it.layer(testLayer)("AntigravityDriver", (it) => {
yield* Deferred.await(spawned);
expect(nativeLaunches(h)).toHaveLength(2);
expect(yield* nativeLaunches(h)[1]!.handle.isRunning).toBe(true);
yield* TestClock.adjust("90 seconds");
yield* TestClock.adjust("5 minutes");
expect(Exit.isFailure(yield* Fiber.join(logout))).toBe(true);
yield* assertProcessesClosed(h, oldLaunches);
yield* assertProcessesClosed(h);
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/provider/Drivers/AntigravityDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,9 @@ export const AntigravityDriver: ScientProviderDriver<
},
Effect.scoped,
Effect.timeoutOrElse({
duration: "90 seconds",
// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes.
duration: "5 minutes",
// SCIENT-FORK:END
orElse: () =>
Effect.fail(
new ProviderDriverError({
Expand Down
2 changes: 1 addition & 1 deletion docs/user/providers-antigravity.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ longer want that credential method available.

## Troubleshooting

Health checks, model refresh, and sign-out allow up to 90 seconds for the official
Installation checks, model refresh, and sign-out allow up to 5 minutes for the official
runtime to start, which can be slow on some computers. Explicit refresh uses saved
credentials and does not launch a login page. Automatic checks verify installation
only. Google controls account eligibility and limits; Scient does not silently
Expand Down
10 changes: 9 additions & 1 deletion packages/provider-acp/src/server/AcpSessionRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1554,9 +1554,17 @@ export const make = (
...(options.spawn.cwd ? { cwd: options.spawn.cwd } : {}),
...(spawnEnvironment ? { env: spawnEnvironment } : {}),
extendEnv: options.spawn.extendEnv ?? true,
// SCIENT-FORK:START — Windows owns the tree with taskkill /T, not a group.
// A detached agent has no console, so every console program it starts
// (Antigravity's own inner process included) opens a visible window.
// The host decides, not the teardown platform a test may simulate.
...(options.ownDetachedProcessGroup === undefined
? {}
: { detached: options.ownDetachedProcessGroup }),
: {
detached:
options.ownDetachedProcessGroup && (yield* HostProcess.Platform) !== "win32",
}),
// SCIENT-FORK:END
shell: containedSpawnCommand.shell,
}),
)
Expand Down
Loading