Skip to content

Commit 3a1851d

Browse files
authored
feat(settings): split rtk toggle into local and cloud checkboxes
Replace the single rtkEnabled setting with per-modality checkboxes in one settings row: Local (covers local and worktree sessions, feeds agent start/reconnect) and Cloud (feeds cloud run creation and resume), both default on. The per-session rtkEnabled contract to the workspace-server and the rtk_enabled wire field stay unchanged; only the value sources split. Also move the POSTHOG_RTK env mutation into configureProcessEnv, which owns every other per-session process env write, with test coverage for the pin/delete paths. Generated-By: PostHog Code Task-Id: 2d6eed7f-9209-4d1f-be54-ae3e22bf2990
1 parent cb4d216 commit 3a1851d

11 files changed

Lines changed: 93 additions & 33 deletions

File tree

packages/core/src/sessions/sessionService.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ export interface SessionServiceDeps {
300300
};
301301
readonly settings: {
302302
customInstructions?: string | null;
303-
rtkEnabled?: boolean;
303+
rtkEnabledLocal?: boolean;
304+
rtkEnabledCloud?: boolean;
304305
};
305306
usageLimit: { show: (...args: any[]) => any };
306307
readonly addDirectoryDialog: { open: boolean };
@@ -1025,12 +1026,12 @@ export class SessionService {
10251026
this.d.log.warn("Failed to verify workspace", { taskId, err });
10261027
});
10271028

1028-
const { customInstructions, rtkEnabled } = this.d.settings;
1029+
const { customInstructions, rtkEnabledLocal } = this.d.settings;
10291030
const result = await this.d.trpc.agent.reconnect.mutate({
10301031
taskId,
10311032
taskRunId,
10321033
repoPath,
1033-
rtkEnabled,
1034+
rtkEnabled: rtkEnabledLocal,
10341035
apiHost: auth.apiHost,
10351036
projectId: auth.projectId,
10361037
logUrl,
@@ -1361,7 +1362,7 @@ export class SessionService {
13611362
permissionMode: executionMode,
13621363
adapter,
13631364
customInstructions: startCustomInstructions || undefined,
1364-
rtkEnabled: this.d.settings.rtkEnabled,
1365+
rtkEnabled: this.d.settings.rtkEnabledLocal,
13651366
effort: effortLevelSchema.safeParse(reasoningLevel).success
13661367
? (reasoningLevel as EffortLevel)
13671368
: undefined,
@@ -2999,7 +3000,7 @@ export class SessionService {
29993000
artifactIds.length > 0 ? artifactIds : undefined,
30003001
prAuthorshipMode,
30013002
autoPublish: previousState.auto_publish === true || undefined,
3002-
rtkEnabled: this.d.settings.rtkEnabled,
3003+
rtkEnabled: this.d.settings.rtkEnabledCloud,
30033004
runSource: getCloudRunSource(previousState),
30043005
signalReportId:
30053006
typeof previousState.signal_report_id === "string"

packages/core/src/task-detail/taskCreationSaga.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ describe("TaskCreationSaga", () => {
153153
model: "gpt-5.4",
154154
reasoningLevel: "high",
155155
cloudAutoPublish: true,
156-
rtkEnabled: false,
156+
cloudRtkEnabled: false,
157157
});
158158

159159
expect(result.success).toBe(true);

packages/core/src/task-detail/taskCreationSaga.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ export class TaskCreationSaga extends Saga<
402402
sandboxEnvironmentId: input.sandboxEnvironmentId,
403403
prAuthorshipMode,
404404
autoPublish: input.cloudAutoPublish,
405-
rtkEnabled: input.rtkEnabled,
405+
rtkEnabled: input.cloudRtkEnabled,
406406
runSource: input.cloudRunSource ?? "manual",
407407
signalReportId: input.signalReportId,
408408
homeQuickAction: input.homeQuickActionLabel,

packages/core/src/task-detail/taskInput.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface PrepareTaskInputOptions {
2828
channelId?: string;
2929
customInstructions?: string;
3030
autoPublishCloudRuns?: boolean;
31-
rtkEnabled?: boolean;
31+
rtkEnabledCloud?: boolean;
3232
allowNoRepo?: boolean;
3333
}
3434

@@ -63,7 +63,7 @@ export function prepareTaskInput(
6363
cloudRunSource:
6464
options.signalReportId && isCloud ? "signal_report" : undefined,
6565
cloudAutoPublish: isCloud ? options.autoPublishCloudRuns : undefined,
66-
rtkEnabled: options.rtkEnabled,
66+
cloudRtkEnabled: isCloud ? options.rtkEnabledCloud : undefined,
6767
signalReportId: options.signalReportId,
6868
additionalDirectories: isCloud ? undefined : options.additionalDirectories,
6969
channelContext: options.channelContext,

packages/shared/src/task-creation-domain.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ export interface TaskCreationInput {
4343
*/
4444
cloudAutoPublish?: boolean;
4545
/**
46-
* rtk command-output compression for the run. Only false is meaningful:
47-
* it opts the run out of the server-side default (enabled).
46+
* rtk command-output compression for the cloud run. Only false is
47+
* meaningful: it opts the run out of the server-side default (enabled).
4848
*/
49-
rtkEnabled?: boolean;
49+
cloudRtkEnabled?: boolean;
5050
signalReportId?: string;
5151
additionalDirectories?: string[];
5252
/**

packages/ui/src/features/settings/sections/AdvancedSettings.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { useSettingsStore } from "@posthog/ui/features/settings/settingsStore";
1111
import { useSetupStore } from "@posthog/ui/features/setup/setupStore";
1212
import { useTourStore } from "@posthog/ui/features/tour/tourStore";
1313
import { clearApplicationStorage } from "@posthog/ui/utils/clearStorage";
14-
import { Button, Flex, Switch } from "@radix-ui/themes";
14+
import { Button, Checkbox, Flex, Switch, Text } from "@radix-ui/themes";
1515
import { useSyncExternalStore } from "react";
1616

1717
export function AdvancedSettings() {
@@ -27,8 +27,10 @@ export function AdvancedSettings() {
2727
const setAutoPublishCloudRuns = useSettingsStore(
2828
(s) => s.setAutoPublishCloudRuns,
2929
);
30-
const rtkEnabled = useSettingsStore((s) => s.rtkEnabled);
31-
const setRtkEnabled = useSettingsStore((s) => s.setRtkEnabled);
30+
const rtkEnabledLocal = useSettingsStore((s) => s.rtkEnabledLocal);
31+
const setRtkEnabledLocal = useSettingsStore((s) => s.setRtkEnabledLocal);
32+
const rtkEnabledCloud = useSettingsStore((s) => s.rtkEnabledCloud);
33+
const setRtkEnabledCloud = useSettingsStore((s) => s.setRtkEnabledCloud);
3234
const devModeClient = useServiceOptional<DevModeClient>(DEV_MODE_CLIENT);
3335

3436
return (
@@ -45,9 +47,34 @@ export function AdvancedSettings() {
4547
</SettingRow>
4648
<SettingRow
4749
label="Compress command output"
48-
description="Route eligible shell commands through rtk so their verbose output is compressed before it reaches the model, reducing token usage. Applies to local, worktree, and cloud runs"
50+
description="Route eligible shell commands through rtk so their verbose output is compressed before it reaches the model, reducing token usage. Local covers local and worktree sessions"
4951
>
50-
<Switch checked={rtkEnabled} onCheckedChange={setRtkEnabled} size="1" />
52+
<Flex gap="4" align="center">
53+
<Text as="label" size="1">
54+
<Flex gap="1" align="center">
55+
<Checkbox
56+
checked={rtkEnabledLocal}
57+
onCheckedChange={(checked) =>
58+
setRtkEnabledLocal(checked === true)
59+
}
60+
size="1"
61+
/>
62+
Local
63+
</Flex>
64+
</Text>
65+
<Text as="label" size="1">
66+
<Flex gap="1" align="center">
67+
<Checkbox
68+
checked={rtkEnabledCloud}
69+
onCheckedChange={(checked) =>
70+
setRtkEnabledCloud(checked === true)
71+
}
72+
size="1"
73+
/>
74+
Cloud
75+
</Flex>
76+
</Text>
77+
</Flex>
5178
</SettingRow>
5279
<SettingRow
5380
label="Reset onboarding and tours"

packages/ui/src/features/settings/settingsStore.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,16 @@ interface SettingsStore {
154154
// without waiting for an explicit ask.
155155
autoPublishCloudRuns: boolean;
156156
// When on, agent runs compress eligible command output through rtk before it
157-
// reaches the model. Applies to local, worktree, and cloud runs.
158-
rtkEnabled: boolean;
157+
// reaches the model. Split by modality: local covers local and worktree
158+
// sessions, cloud covers cloud runs.
159+
rtkEnabledLocal: boolean;
160+
rtkEnabledCloud: boolean;
159161
setAllowBypassPermissions: (enabled: boolean) => void;
160162
setPreventSleepWhileRunning: (enabled: boolean) => void;
161163
setDebugLogsCloudRuns: (enabled: boolean) => void;
162164
setAutoPublishCloudRuns: (enabled: boolean) => void;
163-
setRtkEnabled: (enabled: boolean) => void;
165+
setRtkEnabledLocal: (enabled: boolean) => void;
166+
setRtkEnabledCloud: (enabled: boolean) => void;
164167

165168
// Terminal
166169
terminalFont: TerminalFont;
@@ -328,15 +331,17 @@ export const useSettingsStore = create<SettingsStore>()(
328331
preventSleepWhileRunning: false,
329332
debugLogsCloudRuns: false,
330333
autoPublishCloudRuns: true,
331-
rtkEnabled: true,
334+
rtkEnabledLocal: true,
335+
rtkEnabledCloud: true,
332336
setAllowBypassPermissions: (enabled) =>
333337
set({ allowBypassPermissions: enabled }),
334338
setPreventSleepWhileRunning: (enabled) =>
335339
set({ preventSleepWhileRunning: enabled }),
336340
setDebugLogsCloudRuns: (enabled) => set({ debugLogsCloudRuns: enabled }),
337341
setAutoPublishCloudRuns: (enabled) =>
338342
set({ autoPublishCloudRuns: enabled }),
339-
setRtkEnabled: (enabled) => set({ rtkEnabled: enabled }),
343+
setRtkEnabledLocal: (enabled) => set({ rtkEnabledLocal: enabled }),
344+
setRtkEnabledCloud: (enabled) => set({ rtkEnabledCloud: enabled }),
340345

341346
// Terminal
342347
terminalFont: "berkeley-mono",
@@ -450,7 +455,8 @@ export const useSettingsStore = create<SettingsStore>()(
450455
preventSleepWhileRunning: state.preventSleepWhileRunning,
451456
debugLogsCloudRuns: state.debugLogsCloudRuns,
452457
autoPublishCloudRuns: state.autoPublishCloudRuns,
453-
rtkEnabled: state.rtkEnabled,
458+
rtkEnabledLocal: state.rtkEnabledLocal,
459+
rtkEnabledCloud: state.rtkEnabledCloud,
454460

455461
// Terminal
456462
terminalFont: state.terminalFont,

packages/ui/src/features/task-detail/hooks/useTaskCreation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ export function useTaskCreation({
326326
channelId,
327327
customInstructions: settings.customInstructions,
328328
autoPublishCloudRuns: settings.autoPublishCloudRuns,
329-
rtkEnabled: settings.rtkEnabled,
329+
rtkEnabledCloud: settings.rtkEnabledCloud,
330330
allowNoRepo,
331331
});
332332

packages/workspace-server/src/services/agent/agent.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -765,17 +765,9 @@ If a repository IS genuinely required, attach one in this priority order:
765765
mockNodeDir,
766766
proxyUrl,
767767
claudeCliPath: this.getClaudeCliPath(),
768+
rtkEnabled: config.rtkEnabled,
768769
});
769770

770-
// The agent auto-detects rtk on PATH; an explicit opt-out from settings
771-
// pins it off for sessions this process spawns. Deleting on the enabled
772-
// path restores auto-detection after a re-enable without a restart.
773-
if (config.rtkEnabled === false) {
774-
process.env.POSTHOG_RTK = "0";
775-
} else {
776-
delete process.env.POSTHOG_RTK;
777-
}
778-
779771
const isPreview = taskId === "__preview__";
780772

781773
const agent = new Agent({

packages/workspace-server/src/services/agent/auth-adapter.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,27 @@ describe("AgentAuthAdapter", () => {
242242
expect(process.env.CLAUDE_CODE_EXECUTABLE).toBe("/mock/claude-cli.js");
243243
expect(process.env.POSTHOG_PROJECT_ID).toBe("1");
244244
});
245+
246+
it.each([
247+
{ rtkEnabled: false, expected: "0" },
248+
{ rtkEnabled: true, expected: undefined },
249+
{ rtkEnabled: undefined, expected: undefined },
250+
])(
251+
"pins POSTHOG_RTK for rtkEnabled=$rtkEnabled",
252+
async ({ rtkEnabled, expected }) => {
253+
// A stale value from a previous session must not leak into an
254+
// enabled/default session — the enabled path deletes, not skips.
255+
process.env.POSTHOG_RTK = "0";
256+
257+
await adapter.configureProcessEnv({
258+
credentials: baseCredentials,
259+
mockNodeDir: "/mock/node",
260+
proxyUrl: "http://127.0.0.1:9999",
261+
claudeCliPath: "/mock/claude-cli.js",
262+
rtkEnabled,
263+
});
264+
265+
expect(process.env.POSTHOG_RTK).toBe(expected);
266+
},
267+
);
245268
});

0 commit comments

Comments
 (0)