diff --git a/apps/mobile/src/app/settings/index.tsx b/apps/mobile/src/app/settings/index.tsx
index d5784feddb..79ac5c10f1 100644
--- a/apps/mobile/src/app/settings/index.tsx
+++ b/apps/mobile/src/app/settings/index.tsx
@@ -199,6 +199,8 @@ export default function SettingsScreen() {
const setAutoPublishCloudRuns = usePreferencesStore(
(s) => s.setAutoPublishCloudRuns,
);
+ const rtkEnabledCloud = usePreferencesStore((s) => s.rtkEnabledCloud);
+ const setRtkEnabledCloud = usePreferencesStore((s) => s.setRtkEnabledCloud);
const defaultMessagingMode = useMessagingModeStore((s) => s.defaultMode);
const setDefaultMessagingMode = useMessagingModeStore(
(s) => s.setDefaultMode,
@@ -427,7 +429,6 @@ export default function SettingsScreen() {
}
/>
+
+ }
+ />
{/* Integrations */}
diff --git a/apps/mobile/src/app/task/[id].tsx b/apps/mobile/src/app/task/[id].tsx
index 485cc79ba9..b2c4c4af75 100644
--- a/apps/mobile/src/app/task/[id].tsx
+++ b/apps/mobile/src/app/task/[id].tsx
@@ -304,6 +304,7 @@ export default function TaskDetailScreen() {
model: composerModel,
reasoningEffort: supportsReasoning ? composerReasoning : undefined,
initialPermissionMode: composerMode,
+ rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
});
setTask(updatedTask);
await connectToTask(updatedTask);
@@ -478,6 +479,7 @@ export default function TaskDetailScreen() {
const updatedTask = await runTaskInCloud(taskId, {
resumeFromRunId: task.latest_run?.id,
+ rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
});
setTask(updatedTask);
await connectToTask(updatedTask);
diff --git a/apps/mobile/src/app/task/index.tsx b/apps/mobile/src/app/task/index.tsx
index 882d1b92c0..75fe35e96a 100644
--- a/apps/mobile/src/app/task/index.tsx
+++ b/apps/mobile/src/app/task/index.tsx
@@ -352,6 +352,7 @@ export default function NewTaskScreen() {
reasoningEffort: supportsReasoning ? reasoning : undefined,
initialPermissionMode: mode,
autoPublish: usePreferencesStore.getState().autoPublishCloudRuns,
+ rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
...(signalReport
? {
runSource: "signal_report" as const,
diff --git a/apps/mobile/src/features/inbox/components/TinderView.tsx b/apps/mobile/src/features/inbox/components/TinderView.tsx
index caeae12e87..cc034d6ceb 100644
--- a/apps/mobile/src/features/inbox/components/TinderView.tsx
+++ b/apps/mobile/src/features/inbox/components/TinderView.tsx
@@ -16,6 +16,7 @@ import {
useSafeAreaInsets,
} from "react-native-safe-area-context";
import { MarkdownText } from "@/features/chat/components/MarkdownText";
+import { usePreferencesStore } from "@/features/preferences/stores/preferencesStore";
import { createTask, runTaskInCloud } from "@/features/tasks/api";
import { DEFAULT_MODEL } from "@/features/tasks/composer/options";
import type {
@@ -256,6 +257,7 @@ export function TinderView({
initialPermissionMode: "plan",
runSource: "signal_report",
signalReportId: report.id,
+ rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
});
acceptReport(report.id);
diff --git a/apps/mobile/src/features/preferences/stores/preferencesStore.ts b/apps/mobile/src/features/preferences/stores/preferencesStore.ts
index bdf8a3b64f..627d9080c9 100644
--- a/apps/mobile/src/features/preferences/stores/preferencesStore.ts
+++ b/apps/mobile/src/features/preferences/stores/preferencesStore.ts
@@ -83,6 +83,9 @@ interface PreferencesState {
autoPublishCloudRuns: boolean;
setAutoPublishCloudRuns: (enabled: boolean) => void;
+
+ rtkEnabledCloud: boolean;
+ setRtkEnabledCloud: (enabled: boolean) => void;
}
export const usePreferencesStore = create()(
@@ -127,6 +130,9 @@ export const usePreferencesStore = create()(
autoPublishCloudRuns: true,
setAutoPublishCloudRuns: (enabled) =>
set({ autoPublishCloudRuns: enabled }),
+
+ rtkEnabledCloud: true,
+ setRtkEnabledCloud: (enabled) => set({ rtkEnabledCloud: enabled }),
}),
{
name: "posthog-preferences",
@@ -144,6 +150,7 @@ export const usePreferencesStore = create()(
defaultReasoningEffort: state.defaultReasoningEffort,
lastUsedReasoningEffort: state.lastUsedReasoningEffort,
autoPublishCloudRuns: state.autoPublishCloudRuns,
+ rtkEnabledCloud: state.rtkEnabledCloud,
}),
},
),
diff --git a/apps/mobile/src/features/tasks/api.test.ts b/apps/mobile/src/features/tasks/api.test.ts
index e56acbb760..92dfece844 100644
--- a/apps/mobile/src/features/tasks/api.test.ts
+++ b/apps/mobile/src/features/tasks/api.test.ts
@@ -62,4 +62,19 @@ describe("runTaskInCloud", () => {
const [, init] = mockFetch.mock.calls[0] as [string, RequestInit];
expect(init.body).toBeUndefined();
});
+
+ it("sends rtk_enabled=false when the run opts out", async () => {
+ await runTaskInCloud("task-1", { rtkEnabled: false });
+
+ expect(bodyOf(mockFetch.mock.calls[0])).toMatchObject({
+ rtk_enabled: false,
+ });
+ });
+
+ it("omits rtk_enabled when the run keeps compression on", async () => {
+ await runTaskInCloud("task-1", { rtkEnabled: true });
+
+ const [, init] = mockFetch.mock.calls[0] as [string, RequestInit];
+ expect(init.body).toBeUndefined();
+ });
});
diff --git a/apps/mobile/src/features/tasks/api.ts b/apps/mobile/src/features/tasks/api.ts
index 68fae4895f..909d059b9e 100644
--- a/apps/mobile/src/features/tasks/api.ts
+++ b/apps/mobile/src/features/tasks/api.ts
@@ -436,6 +436,8 @@ export interface RunTaskInCloudOptions {
/** When true, the cloud run pushes its changes and opens a draft PR on
* completion without waiting for an explicit ask. */
autoPublish?: boolean;
+ /** Only false is sent: opts the run out of rtk command-output compression. */
+ rtkEnabled?: boolean;
}
export async function runTaskInCloud(
@@ -460,7 +462,8 @@ export async function runTaskInCloud(
options.initialPermissionMode !== undefined ||
options.runSource !== undefined ||
options.signalReportId !== undefined ||
- options.autoPublish !== undefined);
+ options.autoPublish !== undefined ||
+ options.rtkEnabled === false);
let body: string | undefined;
if (hasOptions) {
@@ -490,6 +493,9 @@ export async function runTaskInCloud(
if (options?.autoPublish !== undefined) {
payload.auto_publish = options.autoPublish;
}
+ if (options?.rtkEnabled === false) {
+ payload.rtk_enabled = false;
+ }
body = JSON.stringify(payload);
}
diff --git a/apps/mobile/src/features/tasks/stores/taskSessionStore.test.ts b/apps/mobile/src/features/tasks/stores/taskSessionStore.test.ts
index 77e5b515c4..db60b6b667 100644
--- a/apps/mobile/src/features/tasks/stores/taskSessionStore.test.ts
+++ b/apps/mobile/src/features/tasks/stores/taskSessionStore.test.ts
@@ -23,6 +23,7 @@ vi.mock("../api", () => ({
sendCloudCommand: vi.fn(),
}));
+import { usePreferencesStore } from "@/features/preferences/stores/preferencesStore";
import { getTask, runTaskInCloud } from "../api";
import type {
CloudTaskUpdatePayload,
@@ -155,6 +156,7 @@ describe("_resumeCloudRun", () => {
vi.clearAllMocks();
useTaskStore.setState({ composerConfigByTaskId: {} });
useTaskSessionStore.setState({ sessions: {} });
+ usePreferencesStore.setState({ rtkEnabledCloud: true });
mockRunTaskInCloud.mockResolvedValue({
id: "t1",
latest_run: { id: "new-run" },
@@ -180,9 +182,24 @@ describe("_resumeCloudRun", () => {
pendingUserMessage: "hi",
reasoningEffort: "low",
initialPermissionMode: "acceptEdits",
+ rtkEnabled: true,
});
});
+ it("forwards the rtk compression opt-out so resume preserves it", async () => {
+ usePreferencesStore.setState({ rtkEnabledCloud: false });
+ mockGetTask.mockResolvedValue(previousTask({ branch: "feature" }));
+
+ await useTaskSessionStore
+ .getState()
+ ._resumeCloudRun("t1", "prev-run", "hi");
+
+ expect(mockRunTaskInCloud).toHaveBeenCalledWith(
+ "t1",
+ expect.objectContaining({ rtkEnabled: false }),
+ );
+ });
+
it("prefers the composer's current selection over the previous run", async () => {
useTaskStore.setState({
composerConfigByTaskId: { t1: { mode: "plan", reasoning: "max" } },
diff --git a/apps/mobile/src/features/tasks/stores/taskSessionStore.ts b/apps/mobile/src/features/tasks/stores/taskSessionStore.ts
index 67792e41ff..967d1dd7b8 100644
--- a/apps/mobile/src/features/tasks/stores/taskSessionStore.ts
+++ b/apps/mobile/src/features/tasks/stores/taskSessionStore.ts
@@ -1165,6 +1165,7 @@ export const useTaskSessionStore = create((set, get) => ({
pendingUserMessage: prompt,
reasoningEffort,
initialPermissionMode,
+ rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
});
const newRun = updatedTask.latest_run;