Skip to content
Open
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
96 changes: 82 additions & 14 deletions apps/mobile/src/app/task/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Text } from "@components/text";
import { DEFAULT_CLAUDE_EXECUTION_MODE } from "@posthog/core/sessions/executionModes";
import { getCloudReasoningConfigOptionId } from "@posthog/core/sessions/cloudSessionConfig";
import { getDefaultExecutionModeForAdapter } from "@posthog/core/sessions/executionModes";
import {
countUserMessages,
getSessionActivityPhase,
} from "@posthog/core/sessions/sessionActivity";
import { isTaskRunning } from "@posthog/core/tasks/taskArchive";
import {
type Adapter,
DEFAULT_CODEX_MODEL,
DEFAULT_GATEWAY_MODEL,
DEFAULT_REASONING_EFFORT,
type ExecutionMode,
getReasoningEffortOptions,
isSupportedReasoningEffort,
type SupportedReasoningEffort,
serializeCloudPrompt,
type Task,
Expand Down Expand Up @@ -57,6 +60,7 @@ import {
import { useTaskSessionStore } from "@/features/tasks/stores/taskSessionStore";
import { useTaskStore } from "@/features/tasks/stores/taskStore";
import { confirmStopRun } from "@/features/tasks/utils/archiveGuard";
import { buildCloudTaskRunConfig } from "@/features/tasks/utils/cloudTaskRunConfig";
import { useScreenInsets } from "@/hooks/useScreenInsets";
import {
ANALYTICS_EVENTS,
Expand Down Expand Up @@ -167,11 +171,37 @@ export default function TaskDetailScreen() {
const [initialComposerMessage, setInitialComposerMessage] = useState<
string | undefined
>();
const composerAdapter: Adapter =
task?.latest_run?.runtime_adapter &&
!session?.terminalStatus &&
composerConfig?.adapter !== task.latest_run.runtime_adapter
? task.latest_run.runtime_adapter
: (composerConfig?.adapter ??
task?.latest_run?.runtime_adapter ??
"claude");
const composerConfigMatchesAdapter =
composerConfig?.adapter === undefined
? composerAdapter === "claude"
: composerConfig.adapter === composerAdapter;
const composerMode: ExecutionMode =
composerConfig?.mode ?? DEFAULT_CLAUDE_EXECUTION_MODE;
const composerModel = composerConfig?.model ?? DEFAULT_GATEWAY_MODEL;
(composerConfigMatchesAdapter ? composerConfig?.mode : undefined) ??
getDefaultExecutionModeForAdapter(composerAdapter);
const composerModel =
(composerConfigMatchesAdapter ? composerConfig?.model : undefined) ??
task?.latest_run?.model ??
(composerAdapter === "codex" ? DEFAULT_CODEX_MODEL : DEFAULT_GATEWAY_MODEL);
const requestedComposerReasoning = composerConfigMatchesAdapter
? composerConfig?.reasoning
: undefined;
const composerReasoning: SupportedReasoningEffort =
composerConfig?.reasoning ?? DEFAULT_REASONING_EFFORT;
requestedComposerReasoning &&
isSupportedReasoningEffort(
composerAdapter,
composerModel,
requestedComposerReasoning,
)
? requestedComposerReasoning
: DEFAULT_REASONING_EFFORT;

const messagingMode = useMessagingMode(taskId);
const queuedCount = useQueuedCount(taskId);
Expand Down Expand Up @@ -311,18 +341,18 @@ export default function TaskDetailScreen() {
)
: text;

const supportsReasoning =
getReasoningEffortOptions("claude", composerModel) !== null;
const updatedTask = await getPostHogApiClient().runTaskInCloud(
taskId,
undefined,
{
resumeFromRunId: task.latest_run?.id,
pendingUserMessage,
adapter: "claude",
model: composerModel,
reasoningLevel: supportsReasoning ? composerReasoning : undefined,
initialPermissionMode: composerMode,
...buildCloudTaskRunConfig({
adapter: composerAdapter,
mode: composerMode,
model: composerModel,
reasoning: composerReasoning,
}),
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
},
);
Expand All @@ -346,6 +376,7 @@ export default function TaskDetailScreen() {
connectToTask,
updateTaskInCache,
composerMode,
composerAdapter,
composerModel,
composerReasoning,
],
Expand Down Expand Up @@ -500,6 +531,19 @@ export default function TaskDetailScreen() {
[taskId, setComposerConfig, setConfigOption],
);

const handleAdapterChange = useCallback(
(value: Adapter) => {
if (!taskId) return;
setComposerConfig(taskId, {
adapter: value,
mode: getDefaultExecutionModeForAdapter(value),
model: value === "codex" ? DEFAULT_CODEX_MODEL : DEFAULT_GATEWAY_MODEL,
reasoning: DEFAULT_REASONING_EFFORT,
});
},
[taskId, setComposerConfig],
);

const handleModelChange = useCallback(
(value: string) => {
if (!taskId) return;
Expand All @@ -513,10 +557,14 @@ export default function TaskDetailScreen() {
(value: SupportedReasoningEffort) => {
if (!taskId) return;
setComposerConfig(taskId, { reasoning: value });
setConfigOption(taskId, "effort", value).catch(() => {});
setConfigOption(
taskId,
getCloudReasoningConfigOptionId(composerAdapter),
value,
).catch(() => {});
usePreferencesStore.getState().setLastUsedReasoningEffort(value);
},
[taskId, setComposerConfig, setConfigOption],
[taskId, composerAdapter, setComposerConfig, setConfigOption],
);

const handleStop = useCallback(() => {
Expand Down Expand Up @@ -568,6 +616,12 @@ export default function TaskDetailScreen() {
undefined,
{
resumeFromRunId: task.latest_run?.id,
...buildCloudTaskRunConfig({
adapter: composerAdapter,
mode: composerMode,
model: composerModel,
reasoning: composerReasoning,
}),
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
},
);
Expand All @@ -584,7 +638,17 @@ export default function TaskDetailScreen() {
"Could not restart the task. Please try again.",
);
}
}, [taskId, task, disconnectFromTask, connectToTask, updateTaskInCache]);
}, [
taskId,
task,
disconnectFromTask,
connectToTask,
updateTaskInCache,
composerAdapter,
composerModel,
composerReasoning,
composerMode,
]);

// Clear retrying once the agent finishes a turn or the run terminates.
useEffect(() => {
Expand Down Expand Up @@ -778,6 +842,9 @@ export default function TaskDetailScreen() {
/>
) : null}
<TaskChatComposer
key={taskId}
adapter={composerAdapter}
canChangeAdapter={!!session?.terminalStatus}
onSend={handleSendPrompt}
restoredDraft={restoredDraft}
editing={!!editingQueuedId}
Expand All @@ -791,6 +858,7 @@ export default function TaskDetailScreen() {
mode={composerMode}
model={composerModel}
reasoning={composerReasoning}
onAdapterChange={handleAdapterChange}
onModeChange={handleModeChange}
onModelChange={handleModelChange}
onReasoningChange={handleReasoningChange}
Expand Down
Loading
Loading