From 51239d97378d6a45012654ce1d0e8f4d8e1f5cf6 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Fri, 6 Nov 2026 01:02:08 -0800 Subject: [PATCH 1/2] test(server): Grok and Antigravity agents start with their thread id --- .../Adapters/GrokAdapterV2.test.ts | 33 +++++++++++++-- .../Drivers/AntigravityDriver.test.ts | 41 ++++++++++++++++++- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts index dec55480af300..f709653384399 100644 --- a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts @@ -1,6 +1,7 @@ import * as NodeCrypto from "@effect/platform-node/NodeCrypto"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { + EnvironmentId, ProjectId, MessageId, NodeId, @@ -246,11 +247,16 @@ describe("Grok launch permission mode", () => { layerHost, ); - const launchArgs = (runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy) => + const launches = (runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy) => Effect.gen(function* () { - const launches: Array> = []; + const launches: Array<{ + readonly args: ReadonlyArray; + readonly env: Record | undefined; + }> = []; const childProcessSpawner = ChildProcessSpawner.make((command) => { - if (command._tag === "StandardCommand") launches.push(command.args.map(String)); + if (command._tag === "StandardCommand") { + launches.push({ args: command.args.map(String), env: command.options.env }); + } return Effect.fail( PlatformError.systemError({ _tag: "NotFound", @@ -260,6 +266,16 @@ describe("Grok launch permission mode", () => { ); }); const instanceId = ProviderInstanceId.make("grok-launch-test"); + const threadId = ThreadId.make("grok-launch-test"); + yield* (yield* McpProviderSessions.McpProviderSessions).set({ + environmentId: EnvironmentId.make("grok-launch-test"), + threadId, + providerSessionId: "grok-launch-test", + providerInstanceId: instanceId, + endpoint: "http://127.0.0.1:43123/mcp", + authorizationHeader: "Bearer grok-launch-test", + browserToolsAvailable: false, + }); const adapter = yield* makeGrokAdapterV2({ instanceId, settings: LAUNCH_TEST_GROK_SETTINGS, @@ -269,7 +285,7 @@ describe("Grok launch permission mode", () => { }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, childProcessSpawner)); yield* adapter .openSession({ - threadId: ThreadId.make("grok-launch-test"), + threadId, providerSessionId: ProviderSessionId.make("grok-launch-test"), modelSelection: { instanceId, model: "grok-build" }, runtimePolicy, @@ -277,6 +293,8 @@ describe("Grok launch permission mode", () => { .pipe(Effect.scoped, Effect.ignore); return launches; }).pipe(Effect.provideService(HostProcess.Platform, "darwin"), Effect.provide(layerTest)); + const launchArgs = (runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy) => + launches(runtimePolicy).pipe(Effect.map((all) => all.map(({ args }) => args))); const policy = ( runtimeMode: RuntimeMode, @@ -303,6 +321,13 @@ describe("Grok launch permission mode", () => { }), ); + it.effect("launches Grok with the thread id its tools inherit", () => + Effect.gen(function* () { + const [launch] = yield* launches(policy("full-access")); + assert.equal(launch?.env?.T3CODE_THREAD_ID, "grok-launch-test"); + }), + ); + it.effect("launches a thread stored as Auto-accept edits asking", () => Effect.gen(function* () { const snapshot = yield* buildInitialGrokProviderSnapshot(LAUNCH_TEST_GROK_SETTINGS); diff --git a/apps/server/src/provider/Drivers/AntigravityDriver.test.ts b/apps/server/src/provider/Drivers/AntigravityDriver.test.ts index c4486916c7d3c..19bbab796ff99 100644 --- a/apps/server/src/provider/Drivers/AntigravityDriver.test.ts +++ b/apps/server/src/provider/Drivers/AntigravityDriver.test.ts @@ -3,7 +3,10 @@ import * as NodeServices from "@effect/platform-node/NodeServices"; import { expect, it } from "@effect/vitest"; import { ANTIGRAVITY_DEFAULT_MODEL, + EnvironmentId, ProviderInstanceId, + ProviderSessionId, + ThreadId, type AntigravitySettings, } from "@t3tools/contracts"; import * as HostProcess from "@t3tools/shared/HostProcess"; @@ -28,6 +31,7 @@ import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEve import * as McpProviderSessions from "@t3tools/provider-core/server/McpProviderSessions"; import * as ModelManifest from "../ModelManifest.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; +import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; import { AntigravityDriver } from "./AntigravityDriver.ts"; import * as ProviderHostLive from "../ProviderHostLive.ts"; import * as ServerSecretStore from "../../auth/ServerSecretStore.ts"; @@ -124,6 +128,7 @@ const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* ( tempDirectory: string | undefined; handle: ChildProcessSpawner.ChildProcessHandle; }> = []; + const agentThreadIds: Array = []; const layerInstallation = Layer.mock(AntigravityInstallation.AntigravityInstallation)({ managedDirectory: root, @@ -160,12 +165,15 @@ const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* ( Effect.gen(function* () { if (command._tag !== "StandardCommand") return yield* Effect.die("Unexpected process pipeline."); - const handle = yield* spawner.spawn(command); const environment = command.options.env ?? {}; const env = (name: string) => { const value = environment[name]; return Redacted.isRedacted(value) ? Redacted.value(value) : value; }; + if (environment.ANTIGRAVITY_HARNESS_PATH !== undefined) { + agentThreadIds.push(env("T3CODE_THREAD_ID")); + } + const handle = yield* spawner.spawn(command); launches.push({ command: command.command, args: command.args.map(String), @@ -224,6 +232,7 @@ const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* ( } }); return { + instanceId, instance, refresh, fs, @@ -238,6 +247,7 @@ const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* ( acquisitions, releases, launches, + agentThreadIds, readRequests, assertClosed, }; @@ -359,6 +369,35 @@ it.layer(layerTest)("AntigravityDriver", (it) => { }).pipe(Effect.scoped), ); + it.effect("launches a thread's agent with the thread id its tools inherit", () => + Effect.gen(function* () { + const h = yield* makeHarness(); + const threadId = ThreadId.make("antigravity-thread-env"); + yield* (yield* McpProviderSessions.McpProviderSessions).set({ + environmentId: EnvironmentId.make("antigravity-thread-env"), + threadId, + providerSessionId: "antigravity-thread-env", + providerInstanceId: h.instanceId, + endpoint: "http://127.0.0.1:43123/mcp", + authorizationHeader: "Bearer antigravity-thread-env", + browserToolsAvailable: false, + }); + yield* h.instance.orchestrationAdapter + .openSession({ + threadId, + providerSessionId: ProviderSessionId.make("antigravity-thread-env"), + modelSelection: { instanceId: h.instanceId, model: ANTIGRAVITY_DEFAULT_MODEL }, + runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ + runtimeMode: "full-access", + interactionMode: "default", + cwd: process.cwd(), + }), + }) + .pipe(Effect.scoped, Effect.exit); + expect(h.agentThreadIds).toEqual([threadId]); + }).pipe(Effect.scoped), + ); + it.effect.skipIf(windowsHost)("keeps the previous catalog when executable resolution fails", () => Effect.gen(function* () { const h = yield* makeHarness(); From 3c54c0e2a9a5239ad0292bcc2eb3fd8f82b9cef6 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Fri, 6 Nov 2026 01:02:18 -0800 Subject: [PATCH 2/2] fix(server): Grok and Antigravity agents get T3CODE_THREAD_ID like other ACP agents The shared ACP adapter hands every flavor a processEnvironment for the agent process, and #30361 put the thread's T3CODE_THREAD_ID in it so that shells, MCP servers and dev servers the agent starts can find their T3 thread. The ACP registry, fx and Kiro flavors merge it into the spawn environment. Grok's runtime builder and the Antigravity driver launched their agents with the instance environment alone, so the variable never reached them or their tools. Grok now merges processEnvironment into its spawn environment the same way fx and Kiro do. The Antigravity driver layers it over the instance environment before its credential and profile filtering, and the runtime input type names the field. Bug: processes a Grok thread starts cannot find their T3 thread, because Grok launches without T3CODE_THREAD_ID Bug: processes an Antigravity thread starts cannot find their T3 thread, because Antigravity launches without T3CODE_THREAD_ID --- .../orchestration-v2/Adapters/AntigravityAdapterV2.ts | 8 +++++++- apps/server/src/provider/Drivers/AntigravityDriver.ts | 9 ++++++--- packages/provider-grok/src/server/adapter.ts | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts index 1490140c1e6e2..d419679d5f64d 100644 --- a/apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts @@ -70,11 +70,17 @@ const AntigravityProviderCapabilitiesV2 = { }, } satisfies OrchestrationV2ProviderCapabilities; +export type AntigravityRuntimeInput = Omit< + AntigravityAcpRuntimeInput, + "spawn" | "childProcessSpawner" +> & + Pick; + export interface AntigravityAdapterV2Options { readonly instanceId: ProviderInstanceId; readonly selfInvocation: SelfInvocation; readonly makeRuntime: ( - input: Omit, + input: AntigravityRuntimeInput, ) => Effect.Effect< AcpSessionRuntime.AcpSessionRuntime["Service"], EffectAcpErrors.AcpError | ProviderSetupError, diff --git a/apps/server/src/provider/Drivers/AntigravityDriver.ts b/apps/server/src/provider/Drivers/AntigravityDriver.ts index cad62882e6813..00ad39e50566e 100644 --- a/apps/server/src/provider/Drivers/AntigravityDriver.ts +++ b/apps/server/src/provider/Drivers/AntigravityDriver.ts @@ -57,7 +57,10 @@ import { } from "../acp/AntigravitySessionFiles.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; -import { makeAntigravityAdapterV2 } from "../../orchestration-v2/Adapters/AntigravityAdapterV2.ts"; +import { + makeAntigravityAdapterV2, + type AntigravityRuntimeInput, +} from "../../orchestration-v2/Adapters/AntigravityAdapterV2.ts"; import { makeAcpNativeLoggerFactory } from "@t3tools/provider-acp/server/nativeLogging"; import { ProviderDriverError } from "../Errors.ts"; import { makeAntigravityProvider } from "../AntigravityProvider.ts"; @@ -182,7 +185,7 @@ export const AntigravityDriver: ProviderDriver< ); const makeRuntime = Effect.fn("AntigravityDriver.makeRuntime")(function* ( - input: Omit, + input: AntigravityRuntimeInput, ): Effect.fn.Return< AcpSessionRuntime.AcpSessionRuntime["Service"], AcpError | ProviderSetupError, @@ -260,7 +263,7 @@ export const AntigravityDriver: ProviderDriver< installation: executable, profile, cwd: input.cwd, - baseEnv: processEnvironment, + baseEnv: { ...processEnvironment, ...input.processEnvironment }, auth, runtimeTempDirectory, }), diff --git a/packages/provider-grok/src/server/adapter.ts b/packages/provider-grok/src/server/adapter.ts index 9ed1368f16984..5ab250dee56ed 100644 --- a/packages/provider-grok/src/server/adapter.ts +++ b/packages/provider-grok/src/server/adapter.ts @@ -291,12 +291,12 @@ export function makeGrokAcpAdapterFlavor( }), makeRuntime: options.makeRuntime ?? - (({ runtimePolicy, ...input }) => + (({ runtimePolicy, processEnvironment, ...input }) => makeGrokAcpRuntime({ ...input, interruptPromptOnCancel: input.interruptPromptOnCancel ?? false, grokSettings: options.settings, - environment: options.environment, + environment: { ...options.environment, ...processEnvironment }, runtimeMode: grokLaunchRuntimeMode(runtimePolicy), })), // Auto prompts represent classifier refusals and must reach the user.