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
7 changes: 4 additions & 3 deletions apps/server/scripts/acp-mock-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,11 @@ function modeState(): AcpCompat.SessionModeState {
// "grok-build" product name.
const grokAcpModels: ReadonlyArray<AcpCompat.ModelInfo> = [
{
modelId: "grok-4.6",
modelId: process.env.T3_ACP_GROK_MODEL ?? "grok-4.6",
name: "Grok 4.6",
_meta: {
totalContextTokens: 500_000,
totalContextTokens: Number(process.env.T3_ACP_GROK_CONTEXT_TOKENS ?? 500_000),
contextWindows: [256_000, 500_000],
supportsReasoningEffort: true,
reasoningEffort: initialGrokReasoningEffort ?? "high",
reasoningEfforts: [
Expand All @@ -449,7 +450,7 @@ function modelState(): AcpCompat.SessionModelState {
}
const modelId = grokAcpModels.some((model) => model.modelId === currentModelId)
? currentModelId
: "grok-4.6";
: (process.env.T3_ACP_GROK_MODEL ?? "grok-4.6");
return {
currentModelId: modelId,
availableModels: grokAcpModels,
Expand Down
91 changes: 91 additions & 0 deletions apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as PlatformError from "effect/PlatformError";
import * as Path from "effect/Path";
import * as Schema from "effect/Schema";
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
import type * as EffectAcpSchema from "effect-acp/compat";
Expand All @@ -27,6 +28,8 @@ import type { ProviderInstance } from "@t3tools/provider-core/server/driver";
import * as ProviderInstanceRegistry from "../../provider/ProviderInstanceRegistry.ts";
import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
import * as McpProviderSessions from "@t3tools/provider-core/server/McpProviderSessions";
import * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime";
import { handoffBudget } from "@t3tools/provider-core/server/handoffBudget";
import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
import * as RuntimePolicy from "../RuntimePolicy.ts";
import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPolicy";
Expand Down Expand Up @@ -314,6 +317,94 @@ describe("Grok permission prompts", () => {
});
});

describe("Grok model context windows", () => {
const layerHost = TestProviderHost.layer().pipe(Layer.provide(NodeServices.layer));
const layerTest = Layer.mergeAll(
NodeServices.layer,
IdAllocator.layer,
McpProviderSessions.layer,
layerHost,
);

it.effect("budgets handoffs with the selected Grok model's window", () =>
Effect.gen(function* () {
const instanceId = ProviderInstanceId.make("grok-window-test");
const threadId = ThreadId.make("grok-window-test");
const modelSelection = { instanceId, model: "grok-build" };
const policy = runtimePolicy({ runtimeMode: "full-access" });
const path = yield* Path.Path;
const mockAgentPath = yield* path.fromFileUrl(
new URL("../../../scripts/acp-mock-agent.ts", import.meta.url),
);
const adapter = yield* makeGrokAdapterV2({
instanceId,
settings: LAUNCH_TEST_GROK_SETTINGS,
environment: {},
hostPlatform: "linux",
selfInvocation: yield* resolveSelfInvocation(),
makeRuntime: (input) =>
Effect.gen(function* () {
const context = yield* Layer.build(
AcpSessionRuntime.layer({
...input,
spawn: {
command: process.execPath,
args: [mockAgentPath],
cwd: process.cwd(),
env: {
T3_ACP_SESSION_LIFECYCLE: "1",
T3_ACP_GROK_MODEL: "grok-4.7",
T3_ACP_GROK_CONTEXT_TOKENS: "256000",
},
},
authMethodId: "test",
}),
);
return yield* AcpSessionRuntime.AcpSessionRuntime.pipe(Effect.provide(context));
}),
});
const runtime = yield* adapter.openSession({
threadId,
providerSessionId: ProviderSessionId.make("grok-window-test"),
modelSelection,
runtimePolicy: policy,
});
const providerThread = yield* runtime.ensureThread({
threadId,
modelSelection,
runtimePolicy: policy,
});
const budgetInput = {
tokenCap: 16_000,
userText: "Continue",
attachments: [],
providerThread,
nativeContextEstimate: 160_684,
};
assert.isNull(providerThread.contextUsage);
assert.equal(handoffBudget(budgetInput), 0);
assert.equal(
handoffBudget({
...budgetInput,
modelContextWindow: runtime.getModelContextWindow?.({ instanceId, model: "grok-4.7" }),
}),
16_000,
);
assert.equal(runtime.getModelContextWindow?.({ instanceId, model: "grok-4.7" }), 256_000);
assert.equal(runtime.getModelContextWindow?.({ instanceId, model: " grok-4.7 " }), 256_000);
for (const model of ["custom-model", "grok-build", "toString"]) {
assert.isUndefined(runtime.getModelContextWindow?.({ instanceId, model }));
}
assert.isUndefined(
runtime.getModelContextWindow?.({
instanceId: ProviderInstanceId.make("another-grok"),
model: "grok-4.7",
}),
);
}).pipe(Effect.scoped, Effect.provide(layerTest)),
);
});

describe("Grok launch permission mode", () => {
const layerHost = TestProviderHost.layer().pipe(Layer.provide(NodeServices.layer));
const layerTest = Layer.mergeAll(
Expand Down
14 changes: 14 additions & 0 deletions packages/provider-acp/src/server/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ export interface AcpAdapterV2Flavor {
ChildProcessSpawner.ChildProcessSpawner | Crypto.Crypto | Scope.Scope
>;
readonly resolveModelId?: (selection: ModelSelection) => string | undefined;
readonly getModelContextWindow?: (
selection: ModelSelection,
session: AcpSessionRuntime.AcpSessionRuntimeStartResult,
) => number | undefined;
readonly applyModelSelection?: (input: {
readonly runtime: AcpSessionRuntime.AcpSessionRuntime["Service"];
readonly startResult: AcpSessionRuntime.AcpSessionRuntimeStartResult;
Expand Down Expand Up @@ -6808,6 +6812,16 @@ export const makeAcpAdapterV2 = Effect.fn("makeAcpAdapterV2")(function* (
providerSessionId: input.providerSessionId,
providerSession,
events: Stream.fromEffectRepeat(Queue.take(events)),
...(flavor.getModelContextWindow === undefined
? {}
: {
getModelContextWindow: (selection) => {
const session = Ref.getUnsafe(activeSessionSetup);
return session === null
? undefined
: flavor.getModelContextWindow?.(selection, session);
},
}),
...(postSettleContinuationEnabled
? {
hasPendingBackgroundWork: Effect.gen(function* () {
Expand Down
14 changes: 14 additions & 0 deletions packages/provider-grok/src/server/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
} from "./xaiAcpExtension.ts";
import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment";
import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPolicy";
import { sessionModelStateFromInitialize } from "@t3tools/provider-acp/server/runtimeModel";
import * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime";
import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers";
import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
Expand Down Expand Up @@ -249,6 +250,19 @@ export function makeGrokAcpAdapterFlavor(
supportsImagePrompts: true,
supportsCompaction: true,
resolveModelId: (selection) => resolveGrokAcpBaseModelId(selection.model),
getModelContextWindow: (selection, session) => {
if (selection.instanceId !== options.instanceId) return undefined;
const modelId = resolveGrokAcpBaseModelId(selection.model);
const models =
session.sessionSetupResult.models ??
sessionModelStateFromInitialize(session.initializeResult);
const window = models?.availableModels.find((model) => model.modelId === modelId)?._meta
?.totalContextTokens;
// contextWindows includes selectable larger windows; totalContextTokens is the default.
return typeof window === "number" && Number.isSafeInteger(window) && window > 0
? window
: undefined;
},
applyModelSelection: ({ runtime, startResult, modelSelection }) =>
Effect.gen(function* () {
const legacy = startResult.initializeResult.protocolVersion === 1;
Expand Down
Loading