Skip to content
Draft
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
2 changes: 1 addition & 1 deletion apps/mobile/src/app/task/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Text } from "@components/text";
import type { Task } from "@posthog/shared";
import { useQueryClient } from "@tanstack/react-query";
import * as Haptics from "expo-haptics";
import { useLocalSearchParams, useRouter } from "expo-router";
Expand Down Expand Up @@ -51,7 +52,6 @@ import {
} from "@/features/tasks/stores/pendingTaskPromptStore";
import { useTaskSessionStore } from "@/features/tasks/stores/taskSessionStore";
import { useTaskStore } from "@/features/tasks/stores/taskStore";
import type { Task } from "@/features/tasks/types";
import {
confirmStopRun,
isTaskRunning,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Text } from "@components/text";
import type { Task } from "@posthog/shared";
import * as Haptics from "expo-haptics";
import { ArrowCounterClockwise } from "phosphor-react-native";
import { useEffect, useRef } from "react";
Expand All @@ -11,7 +12,6 @@ import {
View,
} from "react-native";
import { TaskStatusIcon } from "@/features/tasks/components/TaskStatusIcon";
import type { Task } from "@/features/tasks/types";
import { useThemeColors } from "@/lib/theme";

const SWIPE_THRESHOLD = 60;
Expand Down
16 changes: 9 additions & 7 deletions apps/mobile/src/features/tasks/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import type { Adapter } from "@posthog/shared";
import type {
Adapter,
CreateTaskAutomationOptions,
StoredLogEntry,
Task,
TaskAutomation,
TaskRun,
UpdateTaskAutomationOptions,
} from "@posthog/shared";
import type {
SandboxCustomImage,
SandboxEnvironment,
Expand All @@ -13,14 +21,8 @@ import {
} from "@/lib/api";
import { logger } from "@/lib/logger";
import type {
CreateTaskAutomationOptions,
CreateTaskOptions,
Integration,
StoredLogEntry,
Task,
TaskAutomation,
TaskRun,
UpdateTaskAutomationOptions,
UserGithubIntegration,
} from "./types";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Text } from "@components/text";
import type { TaskAutomation, TaskRun } from "@posthog/shared";
import { ActivityIndicator, Pressable, View } from "react-native";
import type { TaskAutomation, TaskRun } from "../types";
import { formatAutomationScheduleSummary } from "../utils/automationSchedule";
import { getAutomationTemplatePresentation } from "../utils/automationTemplatePresentation";
import { AutomationStatusBadge } from "./AutomationStatusBadge";
Expand Down
6 changes: 2 additions & 4 deletions apps/mobile/src/features/tasks/components/AutomationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Text } from "@components/text";
import type { CreateTaskAutomationOptions } from "@posthog/shared";
import { CaretDown, GithubLogo } from "phosphor-react-native";
import { type MutableRefObject, useEffect, useMemo, useState } from "react";
import {
Expand All @@ -12,10 +13,7 @@ import { MarkdownText } from "@/features/chat/components/MarkdownText";
import { useThemeColors } from "@/lib/theme";
import { RepositoryPickerInline } from "../composer/RepositoryPickerInline";
import { useIntegrations } from "../hooks/useIntegrations";
import type {
CreateTaskAutomationOptions,
RepositorySelection,
} from "../types";
import type { RepositorySelection } from "../types";
import {
type AutomationScheduleDraft,
buildCronExpression,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Text } from "@components/text";
import type { TaskAutomation, TaskRun } from "@posthog/shared";
import { format, formatDistanceToNow } from "date-fns";
import { memo } from "react";
import { Pressable, View } from "react-native";
import type { TaskAutomation, TaskRun } from "../types";
import { formatAutomationScheduleSummary } from "../utils/automationSchedule";
import { getAutomationTemplatePresentation } from "../utils/automationTemplatePresentation";
import { AutomationStatusBadge } from "./AutomationStatusBadge";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Text } from "@components/text";
import type { TaskAutomation } from "@posthog/shared";
import { Plus } from "phosphor-react-native";
import {
ActivityIndicator,
Expand All @@ -10,7 +11,6 @@ import {
import { useThemeColors } from "@/lib/theme";
import { useAutomations } from "../hooks/useAutomations";
import { useTasks } from "../hooks/useTasks";
import type { TaskAutomation } from "../types";
import { AutomationItem } from "./AutomationItem";

interface AutomationListProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Text } from "@components/text";
import type { TaskRun } from "@posthog/shared";
import { View } from "react-native";
import type { TaskRun } from "../types";
import { getAutomationStatusPresentation } from "../utils/automationStatus";

interface AutomationStatusBadgeProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Task, TaskRun } from "@posthog/shared";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createElement } from "react";
import { act, create } from "react-test-renderer";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { Task, TaskRun } from "../types";

const { mockUseAuthStore, mockGetImages, mockGetEnvironments } = vi.hoisted(
() => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Text } from "@components/text";
import type { Task } from "@posthog/shared";
import { Cube } from "phosphor-react-native";
import { View } from "react-native";
import { toRgba } from "@/lib/theme";
import { useCustomImageName } from "../hooks/useCustomImageName";
import type { Task } from "../types";

// Theme tokens have no violet; a fixed Radix violet-9 mirrors the desktop
// custom-image badge and reads well in both light and dark.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Task } from "@posthog/shared";
import * as Haptics from "expo-haptics";
import { Archive, ArrowCounterClockwise } from "phosphor-react-native";
import { useEffect, useRef } from "react";
Expand All @@ -10,7 +11,6 @@ import {
View,
} from "react-native";
import { useThemeColors } from "@/lib/theme";
import type { Task } from "../types";
import {
confirmArchiveRunningTask,
isTaskRunning,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Task } from "@posthog/shared";
import { createElement } from "react";
import { act, create } from "react-test-renderer";
import { describe, expect, it, vi } from "vitest";
import type { Task } from "../types";
import { TaskItem } from "./TaskItem";

vi.mock("phosphor-react-native", () => ({
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/features/tasks/components/TaskItem.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Text } from "@components/text";
import type { Task } from "@posthog/shared";
import { differenceInHours, format, formatDistanceToNow } from "date-fns";
import { Check, GitPullRequest } from "phosphor-react-native";
import { memo } from "react";
import { Linking, Pressable, View } from "react-native";
import { parseGithubIssueUrl } from "@/lib/githubIssueUrl";
import { useThemeColors } from "@/lib/theme";
import type { Task } from "../types";
import { TaskStatusIcon } from "./TaskStatusIcon";

function PrBadge({ prUrl, number }: { prUrl: string; number: number }) {
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/features/tasks/components/TaskList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Text } from "@components/text";
import type { Task } from "@posthog/shared";
import * as Haptics from "expo-haptics";
import { Archive, GitBranch, Plus, Sparkle, X } from "phosphor-react-native";
import { useCallback, useMemo, useState } from "react";
Expand All @@ -14,7 +15,6 @@ import { useTasks } from "../hooks/useTasks";
import { useUserIntegrations } from "../hooks/useUserIntegrations";
import { useArchivedTasksStore } from "../stores/archivedTasksStore";
import { taskActivityTimestamp, useTaskStore } from "../stores/taskStore";
import type { Task } from "../types";
import { GitHubConnectionPrompt } from "./GitHubConnectionPrompt";
import { GitHubLoadNotice } from "./GitHubLoadNotice";
import { SwipeableTaskItem } from "./SwipeableTaskItem";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Task } from "@posthog/shared";
import { describe, expect, it } from "vitest";
import type { Task } from "../types";
import { getTaskStatusIconKind } from "./taskStatusIconKind";

function makeTask(latestRun?: Partial<NonNullable<Task["latest_run"]>>): Task {
Expand Down Expand Up @@ -58,12 +58,6 @@ describe("getTaskStatusIconKind", () => {
),
).toBe("chat");

expect(
getTaskStatusIconKind(
makeTask({ environment: "cloud", status: "started" }),
),
).toBe("chat");

expect(
getTaskStatusIconKind(
makeTask({ environment: "cloud", status: "completed" }),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Task } from "@posthog/shared";
import {
ChatCircle,
CheckCircle,
Expand All @@ -9,7 +10,6 @@ import {
import { memo, useEffect, useRef } from "react";
import { Animated, Easing } from "react-native";
import { useThemeColors } from "@/lib/theme";
import type { Task } from "../types";
import { getTaskStatusIconKind } from "./taskStatusIconKind";

interface TaskStatusIconProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Task } from "../types";
import type { Task } from "@posthog/shared";

export type TaskStatusIconKind =
| "pr"
Expand Down Expand Up @@ -34,7 +34,7 @@ export function getTaskStatusIconKind(task: Task): TaskStatusIconKind {
return "running";
}

if (status === "queued" || status === "started") {
if (status === "queued") {
return "started";
}

Expand Down
27 changes: 27 additions & 0 deletions apps/mobile/src/features/tasks/composer/options.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, expect, it } from "vitest";
import {
DEFAULT_MODEL,
DEFAULT_REASONING,
modelSupportsReasoning,
REASONING_LEVELS,
} from "./options";

describe("task composer options", () => {
it("uses an eligible non-premium default model", () => {
expect(DEFAULT_MODEL).toBe("claude-opus-4-8");
expect(DEFAULT_MODEL).not.toContain("fable");
});

it("derives reasoning defaults and options from shared policy", () => {
expect(DEFAULT_REASONING).toBe("high");
expect(REASONING_LEVELS.map((option) => option.value)).toEqual([
"low",
"medium",
"high",
"xhigh",
"max",
]);
expect(modelSupportsReasoning("claude-opus-4-8")).toBe(true);
expect(modelSupportsReasoning("claude-haiku-4-5")).toBe(false);
});
});
39 changes: 25 additions & 14 deletions apps/mobile/src/features/tasks/composer/options.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
export type ExecutionMode = "default" | "acceptEdits" | "plan" | "auto";
export type ReasoningEffort = "low" | "medium" | "high" | "xhigh" | "max";
import {
DEFAULT_GATEWAY_MODEL,
DEFAULT_REASONING_EFFORT,
defaultEligibleModel,
getReasoningEffortOptions,
type ExecutionMode as SharedExecutionMode,
type SupportedReasoningEffort,
} from "@posthog/shared";

export type ExecutionMode = Extract<
SharedExecutionMode,
"default" | "acceptEdits" | "plan" | "auto"
>;
export type ReasoningEffort = SupportedReasoningEffort;

export const EXECUTION_MODES: {
value: ExecutionMode;
Expand Down Expand Up @@ -62,20 +74,19 @@ export const MODELS: ModelOption[] = [
},
];

export const DEFAULT_EXECUTION_MODE: ExecutionMode = "plan";
export const DEFAULT_MODEL =
defaultEligibleModel(DEFAULT_GATEWAY_MODEL) ??
MODELS.find((model) => defaultEligibleModel(model.value))?.value ??
DEFAULT_GATEWAY_MODEL;
export const DEFAULT_REASONING: ReasoningEffort = DEFAULT_REASONING_EFFORT;

export const REASONING_LEVELS: {
value: ReasoningEffort;
label: string;
}[] = [
{ value: "low", label: "Low" },
{ value: "medium", label: "Medium" },
{ value: "high", label: "High" },
{ value: "xhigh", label: "Extra High" },
{ value: "max", label: "Max" },
];

export const DEFAULT_EXECUTION_MODE: ExecutionMode = "plan";
export const DEFAULT_MODEL = "claude-opus-4-8";
export const DEFAULT_REASONING: ReasoningEffort = "high";
}[] = (getReasoningEffortOptions("claude", DEFAULT_MODEL) ?? []).map(
(option) => ({ value: option.value, label: option.name }),
);

export function modelLabel(value: string): string {
return MODELS.find((m) => m.value === value)?.label ?? value;
Expand All @@ -90,5 +101,5 @@ export function reasoningLabel(value: ReasoningEffort): string {
}

export function modelSupportsReasoning(value: string): boolean {
return MODELS.find((m) => m.value === value)?.supportsReasoning ?? false;
return getReasoningEffortOptions("claude", value) !== null;
}
10 changes: 5 additions & 5 deletions apps/mobile/src/features/tasks/hooks/useAutomations.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import type {
CreateTaskAutomationOptions,
TaskAutomation,
UpdateTaskAutomationOptions,
} from "@posthog/shared";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useAuthStore } from "@/features/auth";
import { logger } from "@/lib/logger";
Expand All @@ -9,11 +14,6 @@ import {
runTaskAutomation,
updateTaskAutomation,
} from "../api";
import type {
CreateTaskAutomationOptions,
TaskAutomation,
UpdateTaskAutomationOptions,
} from "../types";
import { taskKeys } from "./useTasks";

const log = logger.scope("automations-mutations");
Expand Down
3 changes: 2 additions & 1 deletion apps/mobile/src/features/tasks/hooks/useTasks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Task } from "@posthog/shared";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useAuthStore, useUserQuery } from "@/features/auth";
import { logger } from "@/lib/logger";
Expand All @@ -10,7 +11,7 @@ import {
updateTask,
} from "../api";
import { filterAndSortTasks, useTaskStore } from "../stores/taskStore";
import type { CreateTaskOptions, Task } from "../types";
import type { CreateTaskOptions } from "../types";

const log = logger.scope("tasks-mutations");
const ACTIVE_TASK_POLLING_INTERVAL_MS = 5_000;
Expand Down
12 changes: 7 additions & 5 deletions apps/mobile/src/features/tasks/lib/cloudTaskStream.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import {
type CloudTaskUpdatePayload,
isTerminalStatus,
type StoredLogEntry,
type TaskRun,
type TaskRunStatus,
} from "@posthog/shared";
import { fetch } from "expo/fetch";
import { createTimeoutSignal } from "@/lib/api";
import { logger } from "@/lib/logger";
Expand All @@ -8,16 +15,11 @@ import {
streamCloudTask,
} from "../api";
import {
type CloudTaskUpdatePayload,
isKeepaliveEvent,
isPermissionRequestEvent,
isSseErrorEvent,
isTaskRunStateEvent,
isTerminalStatus,
type StoredLogEntry,
type TaskRun,
type TaskRunStateEvent,
type TaskRunStatus,
} from "../types";
import { parseSessionLogs } from "../utils/parseSessionLogs";
import { type SseEvent, SseEventParser } from "./sseParser";
Expand Down
Loading