#!/usr/bin/env node// @effect-diagnostics nodeBuiltinImport:offimport * as NodeFS from "node:fs"; import * as Effect from "effect/Effect";import * as Deferred from "effect/Deferred"; import * as NodeServices from "@effect/platform-node/NodeServices";import * as NodeRuntime from "@effect/platform-node/NodeRuntime"; import * as EffectAcpAgent from "effect-acp/agent";import * as AcpError from "effect-acp/errors";import type * as AcpSchema from "effect-acp/schema"; const requestLogPath = process.env.T3_ACP_REQUEST_LOG_PATH;const exitLogPath = process.env.T3_ACP_EXIT_LOG_PATH;const antigravityProfile = process.env.T3_ACP_ANTIGRAVITY === "1";const emitToolCalls = process.env.T3_ACP_EMIT_TOOL_CALLS === "1";const emitInterleavedAssistantToolCalls = process.env.T3_ACP_EMIT_INTERLEAVED_ASSISTANT_TOOL_CALLS === "1";const emitGenericToolPlaceholders = process.env.T3_ACP_EMIT_GENERIC_TOOL_PLACEHOLDERS === "1";const emitAskQuestion = process.env.T3_ACP_EMIT_ASK_QUESTION === "1";const emitXAiAskUserQuestion = process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION === "1";const emitXAiExitPlanMode = process.env.T3_ACP_EMIT_XAI_EXIT_PLAN_MODE === "1";const emitXAiPlanMdWrite = process.env.T3_ACP_EMIT_XAI_PLAN_MD_WRITE === "1";const emitXAiPromptCompleteThenHang = process.env.T3_ACP_EMIT_XAI_PROMPT_COMPLETE_THEN_HANG === "1";const emitXAiRateLimitThenHang = process.env.T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG === "1";const emitXAiAskUserQuestionThenHang = process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION_THEN_HANG === "1";const emitContentThenHang = process.env.T3_ACP_EMIT_CONTENT_THEN_HANG === "1";const emitPlanThenHang = process.env.T3_ACP_EMIT_PLAN_THEN_HANG === "1";const emitActiveToolThenHang = process.env.T3_ACP_EMIT_ACTIVE_TOOL_THEN_HANG === "1";const emitForeignSessionUpdates = process.env.T3_ACP_EMIT_FOREIGN_SESSION_UPDATES === "1";const waitForResumeRelease = process.env.T3_ACP_WAIT_FOR_RESUME_RELEASE === "1";const completeFirstPromptOnCancel = process.env.T3_ACP_COMPLETE_FIRST_PROMPT_ON_CANCEL === "1";const floodStderr = process.env.T3_ACP_FLOOD_STDERR === "1";const hangPromptForever = process.env.T3_ACP_HANG_PROMPT_FOREVER === "1";const hangFirstPromptForever = process.env.T3_ACP_HANG_FIRST_PROMPT_FOREVER === "1";const emitLateUpdateAfterCancel = process.env.T3_ACP_EMIT_LATE_UPDATE_AFTER_CANCEL === "1";const omitXAiPromptCompleteStopReason = process.env.T3_ACP_OMIT_XAI_PROMPT_COMPLETE_STOP_REASON === "1";const failLoadSession = process.env.T3_ACP_FAIL_LOAD_SESSION === "1";const emitLoadReplay = process.env.T3_ACP_EMIT_LOAD_REPLAY === "1";const hangLoadSessionAfterReplay = process.env.T3_ACP_HANG_LOAD_SESSION_AFTER_REPLAY === "1";const delayLoadSessionAfterReplay = process.env.T3_ACP_DELAY_LOAD_SESSION_AFTER_REPLAY === "1";const loadSessionDelayMs = Number(process.env.T3_ACP_LOAD_SESSION_DELAY_MS ?? "5000");const emitStaleXAiPromptCompleteBeforeSecondHang = process.env.T3_ACP_EMIT_STALE_XAI_PROMPT_COMPLETE_BEFORE_SECOND_HANG === "1";const emitOverlappingXAiPromptCompleteOutOfOrder = process.env.T3_ACP_EMIT_OVERLAPPING_XAI_PROMPT_COMPLETE_OUT_OF_ORDER === "1";const failPrompt = process.env.T3_ACP_FAIL_PROMPT === "1";const failSetConfigOption = process.env.T3_ACP_FAIL_SET_CONFIG_OPTION === "1";const exitOnSetConfigOption = process.env.T3_ACP_EXIT_ON_SET_CONFIG_OPTION === "1";const promptResponseText = process.env.T3_ACP_PROMPT_RESPONSE_TEXT;const initialGrokReasoningEffort = process.env.T3_ACP_INITIAL_GROK_REASONING_EFFORT?.trim() || undefined;const promptDelayMs = Number(process.env.T3_ACP_PROMPT_DELAY_MS ?? "0");const permissionOptionIds = { allowOnce: process.env.T3_ACP_ALLOW_ONCE_OPTION_ID ?? "allow-once", allowAlways: process.env.T3_ACP_ALLOW_ALWAYS_OPTION_ID ?? "allow-always", rejectOnce: process.env.T3_ACP_REJECT_ONCE_OPTION_ID ?? "reject-once",};const omitAllowAlways = process.env.T3_ACP_OMIT_ALLOW_ALWAYS === "1";const permissionRequestCount = Math.max( 1, Number(process.env.T3_ACP_PERMISSION_REQUEST_COUNT ?? "1") || 1,);const sessionId = "mock-session-1"; let currentModeId = antigravityProfile ? "default" : "ask";let currentModelId = antigravityProfile ? "gemini-test-low" : "default";let parameterizedModelPicker = false;let currentReasoning = "medium";let currentContext = "272k";let currentFast = false;let promptCount = 0;let overlappingFirstPromptId: string | undefined;const cancelledSessions = new Set<string>(); function promptIdFromRequestMeta( request: Pick<AcpSchema.PromptRequest, "_meta">,): string | undefined { const meta = request._meta; if (meta === null || typeof meta !== "object") { return undefined; } const promptId = meta.promptId ?? meta.requestId; return typeof promptId === "string" && promptId.length > 0 ? promptId : undefined;} function logExit(reason: string): void { if (!exitLogPath) { return; } NodeFS.appendFileSync(exitLogPath, `${reason}\n`, "utf8");} function writeJsonRpcNotification(method: string, params: unknown): void { process.stdout.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}\n`);} process.once("SIGTERM", () => { logExit("SIGTERM"); process.exit(0);}); process.once("SIGINT", () => { logExit("SIGINT"); process.exit(0);}); process.once("exit", (code) => { logExit(`exit:${code}`);}); function configOptions(): ReadonlyArray<AcpSchema.SessionConfigOption> { if (antigravityProfile) { return [ { id: "model", name: "Model", category: "model", type: "select", currentValue: currentModelId, options: antigravityModels.map((model) => ({ value: model.modelId, name: model.name })), }, { id: "mode", name: "Mode", category: "mode", type: "select", currentValue: currentModeId, options: availableModes.map((mode) => ({ value: mode.id, name: mode.name })), }, ]; } if (parameterizedModelPicker) { const baseOptions: Array<AcpSchema.SessionConfigOption> = [ { id: "mode", name: "Mode", category: "mode", type: "select", currentValue: currentModeId, options: availableModes.map((mode) => ({ value: mode.id, name: mode.name, ...(mode.description ? { description: mode.description } : {}), })), }, { id: "model", name: "Model", category: "model", type: "select", currentValue: currentModelId, options: [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "gpt-5.4", name: "GPT-5.4" }, { value: "claude-opus-4-6", name: "Opus 4.6" }, ], }, ]; switch (currentModelId) { case "gpt-5.4": return [ ...baseOptions, { id: "reasoning", name: "Reasoning", category: "thought_level", type: "select", currentValue: currentReasoning, options: [ { value: "none", name: "None" }, { value: "low", name: "Low" }, { value: "medium", name: "Medium" }, { value: "high", name: "High" }, { value: "extra-high", name: "Extra High" }, ], }, { id: "context", name: "Context", category: "model_config", type: "select", currentValue: currentContext, options: [ { value: "272k", name: "272K" }, { value: "1m", name: "1M" }, ], }, { id: "fast", name: "Fast", category: "model_config", type: "select", currentValue: String(currentFast), options: [ { value: "false", name: "Off" }, { value: "true", name: "Fast" }, ], }, ]; case "composer-2": return [ ...baseOptions, { id: "fast", name: "Fast", category: "model_config", type: "select", currentValue: String(currentFast), options: [ { value: "false", name: "Off" }, { value: "true", name: "Fast" }, ], }, ]; case "claude-opus-4-6": return [ ...baseOptions, { id: "reasoning", name: "Reasoning", category: "thought_level", type: "select", currentValue: currentReasoning, options: [ { value: "low", name: "Low" }, { value: "medium", name: "Medium" }, { value: "high", name: "High" }, ], }, { id: "thinking", name: "Thinking", category: "model_config", type: "boolean", currentValue: true, }, ]; default: return baseOptions; } } return [ { id: "model", name: "Model", category: "model", type: "select" as const, currentValue: currentModelId, options: [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "composer-2[fast=true]", name: "Composer 2 Fast" }, { value: "gpt-5.3-codex[reasoning=medium,fast=false]", name: "Codex 5.3" }, ], }, ];} function modelConfigOptionsFor(modelId: string): ReadonlyArray<AcpSchema.SessionConfigOption> { const previousModelId = currentModelId; try { currentModelId = modelId; return configOptions().filter( (option) => option.category !== "mode" && option.category !== "model", ); } finally { currentModelId = previousModelId; }} function availableModels(): ReadonlyArray<{ readonly value: string; readonly name: string; readonly configOptions: ReadonlyArray<AcpSchema.SessionConfigOption>;}> { return [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "gpt-5.4", name: "GPT-5.4" }, { value: "claude-opus-4-6", name: "Opus 4.6" }, ].map((model) => ({ value: model.value, name: model.name, configOptions: modelConfigOptionsFor(model.value), }));} const antigravityModels = [ { modelId: "gemini-test-low", name: "Gemini Test Low" }, { modelId: "gemini-test-high", name: "Gemini Test High" },] satisfies ReadonlyArray<AcpSchema.ModelInfo>; const availableModes: ReadonlyArray<AcpSchema.SessionMode> = antigravityProfile ? [ { id: "default", name: "Default" }, { id: "auto_edit", name: "Auto edit" }, { id: "yolo", name: "YOLO" }, ] : [ { id: "ask", name: "Ask", description: "Request permission before making any changes", }, { id: "architect", name: "Architect", description: "Design and plan software systems without implementation", }, { id: "code", name: "Code", description: "Write and modify code with full tool access", }, ]; function modeState(): AcpSchema.SessionModeState { return { currentModeId, availableModes, };} // Mirrors the real Grok ACP: it advertises versioned model ids, never the CLI's own// "grok-build" product name, and it rejects unknown ids in session/set_model.const grokAcpModels: ReadonlyArray<AcpSchema.ModelInfo> = [ { modelId: "grok-4.6", name: "Grok 4.6", _meta: { totalContextTokens: 500_000, supportsReasoningEffort: true, reasoningEffort: initialGrokReasoningEffort ?? "high", reasoningEfforts: [ { id: "xhigh", value: "xhigh", label: "Extra High Effort", default: false }, { id: "high", value: "high", label: "High Effort", default: true }, { id: "low", value: "low", label: "Low Effort", default: false }, ], }, }, { modelId: "grok-mock-alt", name: "Grok Mock Alt" },]; function modelState(): AcpSchema.SessionModelState { if (antigravityProfile) { return { currentModelId, availableModels: antigravityModels }; } const modelId = grokAcpModels.some((model) => model.modelId === currentModelId) ? currentModelId : "grok-4.6"; return { currentModelId: modelId, availableModels: grokAcpModels, };} const program = Effect.gen(function* () { const agent = yield* EffectAcpAgent.AcpAgent; const resumeRelease = yield* Deferred.make<void>(); const nativeCancelRequested = yield* Deferred.make<void>(); const nativeCancelRelease = yield* Deferred.make<void>(); const publishAntigravityCommands = (targetSessionId: string) => agent.client.sessionUpdate({ sessionId: targetSessionId, update: { sessionUpdate: "available_commands_update", availableCommands: [ { name: "plan", description: "Plan a task", input: { hint: "task" } }, { name: "logout", description: "Sign out" }, ], }, }); yield* agent.handleInitialize((request) => Effect.gen(function* () { if (floodStderr) { yield* Effect.promise( () => new Promise<void>((resolve) => { process.stderr.write("stderr".repeat(350_000), () => resolve()); }), ); } parameterizedModelPicker = request.clientCapabilities?._meta?.parameterizedModelPicker === true; if (antigravityProfile) { return { protocolVersion: 1, agentInfo: { name: "antigravity-acp", version: "mock" }, agentCapabilities: { loadSession: true, sessionCapabilities: { resume: {} }, auth: { logout: {} }, promptCapabilities: { image: true, embeddedContext: true }, }, authMethods: [{ id: "oauth-personal", name: "Sign in with Google" }], }; } return { protocolVersion: 1, agentCapabilities: { loadSession: true, sessionCapabilities: { resume: {} } }, // Grok advertises model state before any session exists; the provider // health check reads it from here without authenticating. _meta: { modelState: modelState() }, }; }), ); // Mirrors the real agent: the API key method reads GEMINI_API_KEY from the // process environment and rejects when it is missing. yield* agent.handleAuthenticate((request) => !antigravityProfile || request.methodId === "oauth-personal" ? Effect.succeed({}) : request.methodId === "gemini-api-key" && process.env.GEMINI_API_KEY ? Effect.succeed({}) : Effect.fail( AcpError.AcpRequestError.invalidParams( `Mock Antigravity rejected auth method ${request.methodId}.`, ), ), ); if (antigravityProfile) { yield* agent.handleLogout(() => Effect.succeed({})); } yield* agent.handleCreateSession(() => Effect.gen(function* () { if (antigravityProfile) { yield* publishAntigravityCommands(sessionId); } return { sessionId, modes: modeState(), models: modelState(), configOptions: configOptions(), }; }), ); yield* agent.handleResumeSession((request) => Effect.gen(function* () { yield* agent.client.sessionUpdate({ sessionId: request.sessionId, update: { sessionUpdate: "user_message_chunk", content: { type: "text", text: "native-resume-started" }, }, }); if (waitForResumeRelease) { yield* Deferred.await(resumeRelease); } if (antigravityProfile) { yield* publishAntigravityCommands(request.sessionId); } return { modes: modeState(), models: modelState(), configOptions: configOptions(), _meta: { nativeResume: true }, }; }), ); const emitLoadReplayNotifications = (requestedSessionId: string) => { writeJsonRpcNotification("session/update", { _meta: { isReplay: true }, sessionId: requestedSessionId, update: { sessionUpdate: "tool_call", toolCallId: "replay-tool-1", title: "Replay tool", kind: "search", status: "completed", }, }); writeJsonRpcNotification("session/update", { _meta: { isReplay: true }, sessionId: requestedSessionId, update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text: "replayed assistant text" }, }, }); }; yield* agent.handleLoadSession((request) => Effect.gen(function* () { const requestedSessionId = String(request.sessionId ?? sessionId); if (failLoadSession) { return yield* AcpError.AcpRequestError.internalError("Mock load session failure"); } if (hangLoadSessionAfterReplay || delayLoadSessionAfterReplay) {Lines 1–500 of 1370. Load more
#!/usr/bin/env node // @effect-diagnostics nodeBuiltinImport:off import * as NodeFS from "node:fs"; import * as Effect from "effect/Effect"; import * as Deferred from "effect/Deferred"; import * as NodeServices from "@effect/platform-node/NodeServices"; import * as NodeRuntime from "@effect/platform-node/NodeRuntime"; import * as EffectAcpAgent from "effect-acp/agent"; import * as AcpError from "effect-acp/errors"; import type * as AcpSchema from "effect-acp/schema"; const requestLogPath = process.env.T3_ACP_REQUEST_LOG_PATH; const exitLogPath = process.env.T3_ACP_EXIT_LOG_PATH; const antigravityProfile = process.env.T3_ACP_ANTIGRAVITY === "1"; const emitToolCalls = process.env.T3_ACP_EMIT_TOOL_CALLS === "1"; const emitInterleavedAssistantToolCalls = process.env.T3_ACP_EMIT_INTERLEAVED_ASSISTANT_TOOL_CALLS === "1"; const emitGenericToolPlaceholders = process.env.T3_ACP_EMIT_GENERIC_TOOL_PLACEHOLDERS === "1"; const emitAskQuestion = process.env.T3_ACP_EMIT_ASK_QUESTION === "1"; const emitXAiAskUserQuestion = process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION === "1"; const emitXAiExitPlanMode = process.env.T3_ACP_EMIT_XAI_EXIT_PLAN_MODE === "1"; const emitXAiPlanMdWrite = process.env.T3_ACP_EMIT_XAI_PLAN_MD_WRITE === "1"; const emitXAiPromptCompleteThenHang = process.env.T3_ACP_EMIT_XAI_PROMPT_COMPLETE_THEN_HANG === "1"; const emitXAiRateLimitThenHang = process.env.T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG === "1"; const emitXAiAskUserQuestionThenHang = process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION_THEN_HANG === "1"; const emitContentThenHang = process.env.T3_ACP_EMIT_CONTENT_THEN_HANG === "1"; const emitPlanThenHang = process.env.T3_ACP_EMIT_PLAN_THEN_HANG === "1"; const emitActiveToolThenHang = process.env.T3_ACP_EMIT_ACTIVE_TOOL_THEN_HANG === "1"; const emitForeignSessionUpdates = process.env.T3_ACP_EMIT_FOREIGN_SESSION_UPDATES === "1"; const waitForResumeRelease = process.env.T3_ACP_WAIT_FOR_RESUME_RELEASE === "1"; const completeFirstPromptOnCancel = process.env.T3_ACP_COMPLETE_FIRST_PROMPT_ON_CANCEL === "1"; const floodStderr = process.env.T3_ACP_FLOOD_STDERR === "1"; const hangPromptForever = process.env.T3_ACP_HANG_PROMPT_FOREVER === "1"; const hangFirstPromptForever = process.env.T3_ACP_HANG_FIRST_PROMPT_FOREVER === "1"; const emitLateUpdateAfterCancel = process.env.T3_ACP_EMIT_LATE_UPDATE_AFTER_CANCEL === "1"; const omitXAiPromptCompleteStopReason = process.env.T3_ACP_OMIT_XAI_PROMPT_COMPLETE_STOP_REASON === "1"; const failLoadSession = process.env.T3_ACP_FAIL_LOAD_SESSION === "1"; const emitLoadReplay = process.env.T3_ACP_EMIT_LOAD_REPLAY === "1"; const hangLoadSessionAfterReplay = process.env.T3_ACP_HANG_LOAD_SESSION_AFTER_REPLAY === "1"; const delayLoadSessionAfterReplay = process.env.T3_ACP_DELAY_LOAD_SESSION_AFTER_REPLAY === "1"; const loadSessionDelayMs = Number(process.env.T3_ACP_LOAD_SESSION_DELAY_MS ?? "5000"); const emitStaleXAiPromptCompleteBeforeSecondHang = process.env.T3_ACP_EMIT_STALE_XAI_PROMPT_COMPLETE_BEFORE_SECOND_HANG === "1"; const emitOverlappingXAiPromptCompleteOutOfOrder = process.env.T3_ACP_EMIT_OVERLAPPING_XAI_PROMPT_COMPLETE_OUT_OF_ORDER === "1"; const failPrompt = process.env.T3_ACP_FAIL_PROMPT === "1"; const failSetConfigOption = process.env.T3_ACP_FAIL_SET_CONFIG_OPTION === "1"; const exitOnSetConfigOption = process.env.T3_ACP_EXIT_ON_SET_CONFIG_OPTION === "1"; const promptResponseText = process.env.T3_ACP_PROMPT_RESPONSE_TEXT; const initialGrokReasoningEffort = process.env.T3_ACP_INITIAL_GROK_REASONING_EFFORT?.trim() || undefined; const promptDelayMs = Number(process.env.T3_ACP_PROMPT_DELAY_MS ?? "0"); const permissionOptionIds = { allowOnce: process.env.T3_ACP_ALLOW_ONCE_OPTION_ID ?? "allow-once", allowAlways: process.env.T3_ACP_ALLOW_ALWAYS_OPTION_ID ?? "allow-always", rejectOnce: process.env.T3_ACP_REJECT_ONCE_OPTION_ID ?? "reject-once", }; const omitAllowAlways = process.env.T3_ACP_OMIT_ALLOW_ALWAYS === "1"; const permissionRequestCount = Math.max( 1, Number(process.env.T3_ACP_PERMISSION_REQUEST_COUNT ?? "1") || 1, ); const sessionId = "mock-session-1"; let currentModeId = antigravityProfile ? "default" : "ask"; let currentModelId = antigravityProfile ? "gemini-test-low" : "default"; let parameterizedModelPicker = false; let currentReasoning = "medium"; let currentContext = "272k"; let currentFast = false; let promptCount = 0; let overlappingFirstPromptId: string | undefined; const cancelledSessions = new Set<string>(); function promptIdFromRequestMeta( request: Pick<AcpSchema.PromptRequest, "_meta">, ): string | undefined { const meta = request._meta; if (meta === null || typeof meta !== "object") { return undefined; } const promptId = meta.promptId ?? meta.requestId; return typeof promptId === "string" && promptId.length > 0 ? promptId : undefined; } function logExit(reason: string): void { if (!exitLogPath) { return; } NodeFS.appendFileSync(exitLogPath, `${reason}\n`, "utf8"); } function writeJsonRpcNotification(method: string, params: unknown): void { process.stdout.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}\n`); } process.once("SIGTERM", () => { logExit("SIGTERM"); process.exit(0); }); process.once("SIGINT", () => { logExit("SIGINT"); process.exit(0); }); process.once("exit", (code) => { logExit(`exit:${code}`); }); function configOptions(): ReadonlyArray<AcpSchema.SessionConfigOption> { if (antigravityProfile) { return [ { id: "model", name: "Model", category: "model", type: "select", currentValue: currentModelId, options: antigravityModels.map((model) => ({ value: model.modelId, name: model.name })), }, { id: "mode", name: "Mode", category: "mode", type: "select", currentValue: currentModeId, options: availableModes.map((mode) => ({ value: mode.id, name: mode.name })), }, ]; } if (parameterizedModelPicker) { const baseOptions: Array<AcpSchema.SessionConfigOption> = [ { id: "mode", name: "Mode", category: "mode", type: "select", currentValue: currentModeId, options: availableModes.map((mode) => ({ value: mode.id, name: mode.name, ...(mode.description ? { description: mode.description } : {}), })), }, { id: "model", name: "Model", category: "model", type: "select", currentValue: currentModelId, options: [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "gpt-5.4", name: "GPT-5.4" }, { value: "claude-opus-4-6", name: "Opus 4.6" }, ], }, ]; switch (currentModelId) { case "gpt-5.4": return [ ...baseOptions, { id: "reasoning", name: "Reasoning", category: "thought_level", type: "select", currentValue: currentReasoning, options: [ { value: "none", name: "None" }, { value: "low", name: "Low" }, { value: "medium", name: "Medium" }, { value: "high", name: "High" }, { value: "extra-high", name: "Extra High" }, ], }, { id: "context", name: "Context", category: "model_config", type: "select", currentValue: currentContext, options: [ { value: "272k", name: "272K" }, { value: "1m", name: "1M" }, ], }, { id: "fast", name: "Fast", category: "model_config", type: "select", currentValue: String(currentFast), options: [ { value: "false", name: "Off" }, { value: "true", name: "Fast" }, ], }, ]; case "composer-2": return [ ...baseOptions, { id: "fast", name: "Fast", category: "model_config", type: "select", currentValue: String(currentFast), options: [ { value: "false", name: "Off" }, { value: "true", name: "Fast" }, ], }, ]; case "claude-opus-4-6": return [ ...baseOptions, { id: "reasoning", name: "Reasoning", category: "thought_level", type: "select", currentValue: currentReasoning, options: [ { value: "low", name: "Low" }, { value: "medium", name: "Medium" }, { value: "high", name: "High" }, ], }, { id: "thinking", name: "Thinking", category: "model_config", type: "boolean", currentValue: true, }, ]; default: return baseOptions; } } return [ { id: "model", name: "Model", category: "model", type: "select" as const, currentValue: currentModelId, options: [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "composer-2[fast=true]", name: "Composer 2 Fast" }, { value: "gpt-5.3-codex[reasoning=medium,fast=false]", name: "Codex 5.3" }, ], }, ]; } function modelConfigOptionsFor(modelId: string): ReadonlyArray<AcpSchema.SessionConfigOption> { const previousModelId = currentModelId; try { currentModelId = modelId; return configOptions().filter( (option) => option.category !== "mode" && option.category !== "model", ); } finally { currentModelId = previousModelId; } } function availableModels(): ReadonlyArray<{ readonly value: string; readonly name: string; readonly configOptions: ReadonlyArray<AcpSchema.SessionConfigOption>; }> { return [ { value: "default", name: "Auto" }, { value: "composer-2", name: "Composer 2" }, { value: "gpt-5.4", name: "GPT-5.4" }, { value: "claude-opus-4-6", name: "Opus 4.6" }, ].map((model) => ({ value: model.value, name: model.name, configOptions: modelConfigOptionsFor(model.value), })); } const antigravityModels = [ { modelId: "gemini-test-low", name: "Gemini Test Low" }, { modelId: "gemini-test-high", name: "Gemini Test High" }, ] satisfies ReadonlyArray<AcpSchema.ModelInfo>; const availableModes: ReadonlyArray<AcpSchema.SessionMode> = antigravityProfile ? [ { id: "default", name: "Default" }, { id: "auto_edit", name: "Auto edit" }, { id: "yolo", name: "YOLO" }, ] : [ { id: "ask", name: "Ask", description: "Request permission before making any changes", }, { id: "architect", name: "Architect", description: "Design and plan software systems without implementation", }, { id: "code", name: "Code", description: "Write and modify code with full tool access", }, ]; function modeState(): AcpSchema.SessionModeState { return { currentModeId, availableModes, }; } // Mirrors the real Grok ACP: it advertises versioned model ids, never the CLI's own // "grok-build" product name, and it rejects unknown ids in session/set_model. const grokAcpModels: ReadonlyArray<AcpSchema.ModelInfo> = [ { modelId: "grok-4.6", name: "Grok 4.6", _meta: { totalContextTokens: 500_000, supportsReasoningEffort: true, reasoningEffort: initialGrokReasoningEffort ?? "high", reasoningEfforts: [ { id: "xhigh", value: "xhigh", label: "Extra High Effort", default: false }, { id: "high", value: "high", label: "High Effort", default: true }, { id: "low", value: "low", label: "Low Effort", default: false }, ], }, }, { modelId: "grok-mock-alt", name: "Grok Mock Alt" }, ]; function modelState(): AcpSchema.SessionModelState { if (antigravityProfile) { return { currentModelId, availableModels: antigravityModels }; } const modelId = grokAcpModels.some((model) => model.modelId === currentModelId) ? currentModelId : "grok-4.6"; return { currentModelId: modelId, availableModels: grokAcpModels, }; } const program = Effect.gen(function* () { const agent = yield* EffectAcpAgent.AcpAgent; const resumeRelease = yield* Deferred.make<void>(); const nativeCancelRequested = yield* Deferred.make<void>(); const nativeCancelRelease = yield* Deferred.make<void>(); const publishAntigravityCommands = (targetSessionId: string) => agent.client.sessionUpdate({ sessionId: targetSessionId, update: { sessionUpdate: "available_commands_update", availableCommands: [ { name: "plan", description: "Plan a task", input: { hint: "task" } }, { name: "logout", description: "Sign out" }, ], }, }); yield* agent.handleInitialize((request) => Effect.gen(function* () { if (floodStderr) { yield* Effect.promise( () => new Promise<void>((resolve) => { process.stderr.write("stderr".repeat(350_000), () => resolve()); }), ); } parameterizedModelPicker = request.clientCapabilities?._meta?.parameterizedModelPicker === true; if (antigravityProfile) { return { protocolVersion: 1, agentInfo: { name: "antigravity-acp", version: "mock" }, agentCapabilities: { loadSession: true, sessionCapabilities: { resume: {} }, auth: { logout: {} }, promptCapabilities: { image: true, embeddedContext: true }, }, authMethods: [{ id: "oauth-personal", name: "Sign in with Google" }], }; } return { protocolVersion: 1, agentCapabilities: { loadSession: true, sessionCapabilities: { resume: {} } }, // Grok advertises model state before any session exists; the provider // health check reads it from here without authenticating. _meta: { modelState: modelState() }, }; }), ); // Mirrors the real agent: the API key method reads GEMINI_API_KEY from the // process environment and rejects when it is missing. yield* agent.handleAuthenticate((request) => !antigravityProfile || request.methodId === "oauth-personal" ? Effect.succeed({}) : request.methodId === "gemini-api-key" && process.env.GEMINI_API_KEY ? Effect.succeed({}) : Effect.fail( AcpError.AcpRequestError.invalidParams( `Mock Antigravity rejected auth method ${request.methodId}.`, ), ), ); if (antigravityProfile) { yield* agent.handleLogout(() => Effect.succeed({})); } yield* agent.handleCreateSession(() => Effect.gen(function* () { if (antigravityProfile) { yield* publishAntigravityCommands(sessionId); } return { sessionId, modes: modeState(), models: modelState(), configOptions: configOptions(), }; }), ); yield* agent.handleResumeSession((request) => Effect.gen(function* () { yield* agent.client.sessionUpdate({ sessionId: request.sessionId, update: { sessionUpdate: "user_message_chunk", content: { type: "text", text: "native-resume-started" }, }, }); if (waitForResumeRelease) { yield* Deferred.await(resumeRelease); } if (antigravityProfile) { yield* publishAntigravityCommands(request.sessionId); } return { modes: modeState(), models: modelState(), configOptions: configOptions(), _meta: { nativeResume: true }, }; }), ); const emitLoadReplayNotifications = (requestedSessionId: string) => { writeJsonRpcNotification("session/update", { _meta: { isReplay: true }, sessionId: requestedSessionId, update: { sessionUpdate: "tool_call", toolCallId: "replay-tool-1", title: "Replay tool", kind: "search", status: "completed", }, }); writeJsonRpcNotification("session/update", { _meta: { isReplay: true }, sessionId: requestedSessionId, update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text: "replayed assistant text" }, }, }); }; yield* agent.handleLoadSession((request) => Effect.gen(function* () { const requestedSessionId = String(request.sessionId ?? sessionId); if (failLoadSession) { return yield* AcpError.AcpRequestError.internalError("Mock load session failure"); } if (hangLoadSessionAfterReplay || delayLoadSessionAfterReplay) {