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/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(); 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.