Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.

Commit 70e84e9

Browse files
Adopt shared cloud task architecture
Generated-By: PostHog Code Task-Id: 40c57a59-b4e1-4760-8e56-ecd03e9c2f0f
1 parent 7aa997c commit 70e84e9

54 files changed

Lines changed: 807 additions & 1585 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/mobile/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@modelcontextprotocol/ext-apps": "^1.2.2",
2929
"@modelcontextprotocol/sdk": "^1.29.0",
3030
"@posthog/api-client": "workspace:*",
31+
"@posthog/core": "workspace:*",
3132
"@posthog/shared": "workspace:*",
3233
"@react-native-async-storage/async-storage": "^2.2.0",
3334
"@react-native-community/netinfo": "^12.0.1",

apps/mobile/src/app/(tabs)/inbox.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { INBOX_PIPELINE_STATUSES } from "@posthog/core/inbox/reportFiltering";
2+
import type { SignalReport } from "@posthog/shared/domain-types";
13
import { useFocusEffect, useRouter } from "expo-router";
24
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
35
import { View } from "react-native";
@@ -20,12 +22,8 @@ import {
2022
decidedIds,
2123
useDismissedReportsStore,
2224
} from "@/features/inbox/stores/dismissedReportsStore";
23-
import {
24-
DEFAULT_STATUS_FILTER,
25-
useInboxFilterStore,
26-
} from "@/features/inbox/stores/inboxFilterStore";
25+
import { useInboxFilterStore } from "@/features/inbox/stores/inboxFilterStore";
2726
import { useInboxStore } from "@/features/inbox/stores/inboxStore";
28-
import type { SignalReport } from "@/features/inbox/types";
2927
import { buildInboxViewedProperties } from "@/features/inbox/utils";
3028
import { useIntegrations } from "@/features/tasks/hooks/useIntegrations";
3129
import { ANALYTICS_EVENTS, useAnalytics } from "@/lib/analytics";
@@ -74,7 +72,7 @@ export default function InboxScreen() {
7472
statusFilter,
7573
suggestedReviewerFilter,
7674
priorityFilter,
77-
defaultStatusFilter: DEFAULT_STATUS_FILTER,
75+
defaultStatusFilter: INBOX_PIPELINE_STATUSES,
7876
}),
7977
);
8078
}, [

apps/mobile/src/app/inbox/[...id].tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
import { Text } from "@components/text";
2+
import {
3+
formatSignalReportSummaryMarkdown,
4+
inboxStatusLabel,
5+
} from "@posthog/core/inbox/reportPresentation";
6+
import { DISMISSAL_REASON_OPTIONS } from "@posthog/shared";
7+
import type {
8+
ActionabilityJudgmentContent,
9+
SignalFindingContent,
10+
SignalReportPriority,
11+
SignalReportStatus,
12+
SuggestedReviewersArtefact,
13+
} from "@posthog/shared/domain-types";
214
import { differenceInHours, format, formatDistanceToNow } from "date-fns";
315
import * as Haptics from "expo-haptics";
416
import { useLocalSearchParams, useRouter } from "expo-router";
@@ -39,25 +51,13 @@ import {
3951
type ReviewerActionExtra,
4052
SuggestedReviewers,
4153
} from "@/features/inbox/components/SuggestedReviewers";
42-
import { DISMISSAL_REASON_OPTIONS } from "@/features/inbox/constants";
4354
import { useInboxEngagementTracker } from "@/features/inbox/hooks/useInboxEngagementTracker";
4455
import {
4556
useInboxReport,
4657
useInboxReportArtefacts,
4758
useInboxReportSignals,
4859
} from "@/features/inbox/hooks/useInboxReports";
4960
import { useInboxStore } from "@/features/inbox/stores/inboxStore";
50-
import type {
51-
ActionabilityJudgmentContent,
52-
SignalFindingContent,
53-
SignalReportPriority,
54-
SignalReportStatus,
55-
SuggestedReviewersArtefact,
56-
} from "@/features/inbox/types";
57-
import {
58-
formatSignalReportSummaryMarkdown,
59-
inboxStatusLabel,
60-
} from "@/features/inbox/utils";
6161
import { PrStatusBadge } from "@/features/tasks/components/PrStatusBadge";
6262
import {
6363
computeReportAgeHours,

apps/mobile/src/app/task/[id].tsx

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@ import type {
33
CloudTaskQueuedMessage,
44
CloudTaskQueueMoveDirection,
55
} from "@posthog/core/sessions/cloudTaskQueue";
6+
import { DEFAULT_CLAUDE_EXECUTION_MODE } from "@posthog/core/sessions/executionModes";
67
import {
78
countUserMessages,
89
getSessionActivityPhase,
910
} from "@posthog/core/sessions/sessionActivity";
1011
import { isTaskRunning } from "@posthog/core/tasks/taskArchive";
11-
import type { Task } from "@posthog/shared";
12+
import {
13+
DEFAULT_GATEWAY_MODEL,
14+
DEFAULT_REASONING_EFFORT,
15+
type ExecutionMode,
16+
getReasoningEffortOptions,
17+
type SupportedReasoningEffort,
18+
serializeCloudPrompt,
19+
type Task,
20+
} from "@posthog/shared";
1221
import { useQueryClient } from "@tanstack/react-query";
1322
import * as Haptics from "expo-haptics";
1423
import { useLocalSearchParams, useRouter } from "expo-router";
@@ -24,24 +33,14 @@ import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller
2433
import Animated, { useAnimatedStyle } from "react-native-reanimated";
2534
import { FloatingBackButton } from "@/components/FloatingBackButton";
2635
import { usePreferencesStore } from "@/features/preferences/stores/preferencesStore";
27-
import { runTaskInCloud } from "@/features/tasks/api";
2836
import { CustomImageBadge } from "@/features/tasks/components/CustomImageBadge";
2937
import { FloatingTaskHeader } from "@/features/tasks/components/FloatingTaskHeader";
3038
import { PrDiffStatsBadge } from "@/features/tasks/components/PrDiffStatsBadge";
3139
import { PrStatusBadge } from "@/features/tasks/components/PrStatusBadge";
3240
import { StopRunButton } from "@/features/tasks/components/StopRunButton";
3341
import { TaskSessionView } from "@/features/tasks/components/TaskSessionView";
3442
import { buildCloudPromptBlocks } from "@/features/tasks/composer/attachments/buildCloudPrompt";
35-
import { serializeCloudPrompt } from "@/features/tasks/composer/attachments/cloudPrompt";
3643
import type { PendingAttachment } from "@/features/tasks/composer/attachments/types";
37-
import {
38-
DEFAULT_EXECUTION_MODE,
39-
DEFAULT_MODEL,
40-
DEFAULT_REASONING,
41-
type ExecutionMode,
42-
modelSupportsReasoning,
43-
type ReasoningEffort,
44-
} from "@/features/tasks/composer/options";
4544
import { QueuedMessagesDock } from "@/features/tasks/composer/QueuedMessagesDock";
4645
import { TaskChatComposer } from "@/features/tasks/composer/TaskChatComposer";
4746
import {
@@ -134,7 +133,13 @@ export default function TaskDetailScreen() {
134133
// Cleared when the screen unmounts. Matches the desktop super-property.
135134
useActiveTaskAnalyticsContext(task?.signal_report ?? null);
136135

137-
const session = taskId ? getTaskSession(taskId) : undefined;
136+
const session = useTaskSessionStore((state) =>
137+
taskId
138+
? Object.values(state.sessions).find(
139+
(candidate) => candidate.taskId === taskId,
140+
)
141+
: undefined,
142+
);
138143

139144
// Optimistic echo set by the new-task screen (or the terminal-resume path
140145
// below) so the user's prompt appears in the thread immediately, before
@@ -176,14 +181,14 @@ export default function TaskDetailScreen() {
176181
string | undefined
177182
>();
178183
const composerMode: ExecutionMode =
179-
composerConfig?.mode ?? DEFAULT_EXECUTION_MODE;
180-
const composerModel = composerConfig?.model ?? DEFAULT_MODEL;
181-
const composerReasoning: ReasoningEffort =
182-
composerConfig?.reasoning ?? DEFAULT_REASONING;
184+
composerConfig?.mode ?? DEFAULT_CLAUDE_EXECUTION_MODE;
185+
const composerModel = composerConfig?.model ?? DEFAULT_GATEWAY_MODEL;
186+
const composerReasoning: SupportedReasoningEffort =
187+
composerConfig?.reasoning ?? DEFAULT_REASONING_EFFORT;
183188

184189
const messagingMode = useMessagingMode(taskId);
185190
const queuedCount = useQueuedCount(taskId);
186-
const { editingId: editingQueuedId } = useTaskMessageQueue(taskId);
191+
const editingQueuedId = useTaskMessageQueue(taskId ?? "").editingId;
187192
const toggleMessagingMode = useToggleMessagingMode(taskId);
188193
const analytics = useAnalytics();
189194

@@ -317,16 +322,21 @@ export default function TaskDetailScreen() {
317322
)
318323
: text;
319324

320-
const supportsReasoning = modelSupportsReasoning(composerModel);
321-
const updatedTask = await runTaskInCloud(taskId, {
322-
resumeFromRunId: task.latest_run?.id,
323-
pendingUserMessage,
324-
runtimeAdapter: "claude",
325-
model: composerModel,
326-
reasoningEffort: supportsReasoning ? composerReasoning : undefined,
327-
initialPermissionMode: composerMode,
328-
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
329-
});
325+
const supportsReasoning =
326+
getReasoningEffortOptions("claude", composerModel) !== null;
327+
const updatedTask = await getPostHogApiClient().runTaskInCloud(
328+
taskId,
329+
undefined,
330+
{
331+
resumeFromRunId: task.latest_run?.id,
332+
pendingUserMessage,
333+
adapter: "claude",
334+
model: composerModel,
335+
reasoningLevel: supportsReasoning ? composerReasoning : undefined,
336+
initialPermissionMode: composerMode,
337+
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
338+
},
339+
);
330340
setTask(updatedTask);
331341
await connectToTask(updatedTask);
332342
updateTaskInCache(updatedTask);
@@ -513,7 +523,7 @@ export default function TaskDetailScreen() {
513523
);
514524

515525
const handleReasoningChange = useCallback(
516-
(value: ReasoningEffort) => {
526+
(value: SupportedReasoningEffort) => {
517527
if (!taskId) return;
518528
setComposerConfig(taskId, { reasoning: value });
519529
setConfigOption(taskId, "effort", value).catch(() => {});
@@ -566,10 +576,14 @@ export default function TaskDetailScreen() {
566576
setRetrying(true);
567577
disconnectFromTask(taskId);
568578

569-
const updatedTask = await runTaskInCloud(taskId, {
570-
resumeFromRunId: task.latest_run?.id,
571-
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
572-
});
579+
const updatedTask = await getPostHogApiClient().runTaskInCloud(
580+
taskId,
581+
undefined,
582+
{
583+
resumeFromRunId: task.latest_run?.id,
584+
rtkEnabled: usePreferencesStore.getState().rtkEnabledCloud,
585+
},
586+
);
573587
setTask(updatedTask);
574588
await connectToTask(updatedTask);
575589
updateTaskInCache(updatedTask);

0 commit comments

Comments
 (0)