Skip to content
15 changes: 15 additions & 0 deletions apps/server/src/provider/Layers/GrokAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as Ref from "effect/Ref";
import * as Schema from "effect/Schema";
import * as Stream from "effect/Stream";
import * as TestClock from "effect/testing/TestClock";
import type * as EffectAcpSchema from "effect-acp/schema";

import {
ApprovalRequestId,
Expand All @@ -30,6 +31,7 @@ import {
grokPromptSettlementBelongsToContext,
grokTurnCompletionForPromptEpoch,
makeGrokAdapter,
selectGrokPermissionOptionId,
} from "./GrokAdapter.ts";
const decodeGrokSettings = Schema.decodeSync(GrokSettings);

Expand Down Expand Up @@ -93,6 +95,19 @@ const grokAdapterTestLayer = ServerConfig.layerTest(process.cwd(), {
const makeTestAdapter = (binaryPath: string, options?: Parameters<typeof makeGrokAdapter>[1]) =>
makeGrokAdapter(decodeGrokSettings({ binaryPath }), options).pipe(Effect.orDie);

it("falls back to allow_once when Grok omits allow_always", () => {
const request = {
sessionId: "session-1",
toolCall: { toolCallId: "tool-1", title: "run", kind: "execute" },
options: [
{ optionId: "allow-once", name: "Allow once", kind: "allow_once" },
{ optionId: "reject-once", name: "Reject", kind: "reject_once" },
],
} satisfies EffectAcpSchema.RequestPermissionRequest;
assert.equal(selectGrokPermissionOptionId(request, "acceptForSession"), "allow-once");
assert.equal(selectGrokPermissionOptionId(request, "accept"), "allow-once");
Comment thread
greptile-apps[bot] marked this conversation as resolved.
});

it("requires a settlement to match the live Grok turn", () => {
const staleTurnId = TurnId.make("stale-turn");
const replacementTurnId = TurnId.make("replacement-turn");
Expand Down
28 changes: 21 additions & 7 deletions apps/server/src/provider/Layers/GrokAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,26 +191,38 @@ function parseGrokResume(raw: unknown): { sessionId: string } | undefined {
return { sessionId: raw.sessionId.trim() };
}

function selectPermissionOptionId(
export function selectGrokPermissionOptionId(
request: EffectAcpSchema.RequestPermissionRequest,
decision: Exclude<ProviderApprovalDecision, "cancel">,
): string | undefined {
const kind =
const preferredKind =
decision === "acceptForSession"
? "allow_always"
: decision === "accept"
? "allow_once"
: "reject_once";
const option = request.options.find((entry) => entry.kind === kind);
return option?.optionId.trim() || undefined;
const preferred = request.options.find((entry) => entry.kind === preferredKind);
const preferredId = preferred?.optionId.trim();
if (preferredId) {
return preferredId;
}
// Grok 4.6 often omits allow_always. The UI still offers "Always allow this session".
if (decision === "acceptForSession") {
const once = request.options.find((entry) => entry.kind === "allow_once");
const onceId = once?.optionId.trim();
if (onceId) {
return onceId;
}
}
return undefined;
}

function selectAutoApprovedPermissionOption(
request: EffectAcpSchema.RequestPermissionRequest,
): string | undefined {
return (
selectPermissionOptionId(request, "acceptForSession") ??
selectPermissionOptionId(request, "accept")
selectGrokPermissionOptionId(request, "acceptForSession") ??
selectGrokPermissionOptionId(request, "accept")
);
}

Expand Down Expand Up @@ -832,7 +844,9 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte
}),
);
const selectedOptionId =
resolved === "cancel" ? undefined : selectPermissionOptionId(params, resolved);
resolved === "cancel"
? undefined
: selectGrokPermissionOptionId(params, resolved);
return {
outcome: selectedOptionId
? {
Expand Down
Loading