Skip to content
Merged
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
132 changes: 132 additions & 0 deletions packages/core/src/sidebar/taskRunning.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import type { TaskRunStatus } from "@posthog/shared/domain-types";
import { describe, expect, it } from "vitest";
import type { TaskData } from "./sidebarData.types";
import { isTaskActivelyRunning } from "./taskRunning";

const task = (overrides: Partial<TaskData>): TaskData => ({
id: "t",
title: "t",
createdAt: 0,
lastActivityAt: 0,
isGenerating: false,
isUnread: false,
isPinned: false,
needsPermission: false,
repository: null,
isSuspended: false,
folderPath: null,
cloudPrUrl: null,
branchName: null,
linkedBranch: null,
...overrides,
});

describe("isTaskActivelyRunning", () => {
it.each<{
name: string;
environment: "local" | "cloud" | undefined;
status: TaskRunStatus | undefined;
isGenerating: boolean;
expected: boolean;
}>([
// The regression: local runs stay "in_progress" forever, so this must NOT
// count as running or the warning fires on every local task ever run.
{
name: "stale local in_progress with no live prompt",
environment: "local",
status: "in_progress",
isGenerating: false,
expected: false,
},
{
name: "local run with a prompt in flight",
environment: "local",
status: "in_progress",
isGenerating: true,
expected: true,
},
{
name: "finished local run",
environment: "local",
status: "completed",
isGenerating: false,
expected: false,
},
{
name: "idle local task that never ran",
environment: "local",
status: undefined,
isGenerating: false,
expected: false,
},
{
name: "cloud run in progress",
environment: "cloud",
status: "in_progress",
isGenerating: false,
expected: true,
},
{
name: "queued cloud run (not yet running)",
environment: "cloud",
status: "queued",
isGenerating: false,
expected: false,
},
{
name: "completed cloud run",
environment: "cloud",
status: "completed",
isGenerating: false,
expected: false,
},
{
name: "failed cloud run",
environment: "cloud",
status: "failed",
isGenerating: false,
expected: false,
},
{
name: "cancelled cloud run",
environment: "cloud",
status: "cancelled",
isGenerating: false,
expected: false,
},
{
name: "cloud run generating",
environment: "cloud",
status: "in_progress",
isGenerating: true,
expected: true,
},
{
name: "unknown environment with stale in_progress status",
environment: undefined,
status: "in_progress",
isGenerating: false,
expected: false,
},
{
name: "generating before any run environment is recorded",
environment: undefined,
status: undefined,
isGenerating: true,
expected: true,
},
])(
"$name -> $expected",
({ environment, status, isGenerating, expected }) => {
expect(
isTaskActivelyRunning(
task({
taskRunEnvironment: environment,
taskRunStatus: status,
isGenerating,
}),
),
).toBe(expected);
},
);
});
12 changes: 12 additions & 0 deletions packages/core/src/sidebar/taskRunning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { TaskData } from "./sidebarData.types";

// Drives the "Archive running task?" confirmation. Persisted run status is only
// trustworthy for cloud runs; local runs stay "in_progress" forever (nothing
// writes a terminal status when the agent goes idle), so a local run counts as
// running only while a prompt is in flight (isGenerating).
export function isTaskActivelyRunning(task: TaskData): boolean {
if (task.isGenerating) return true;
return (
task.taskRunEnvironment === "cloud" && task.taskRunStatus === "in_progress"
);
}
10 changes: 2 additions & 8 deletions packages/ui/src/features/sidebar/components/SidebarMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isTaskActivelyRunning } from "@posthog/core/sidebar/taskRunning";
import { useHostTRPCClient } from "@posthog/host-router/react";
import { Separator } from "@posthog/quill";
import type { Task } from "@posthog/shared/types";
Expand All @@ -11,10 +12,7 @@ import { useArchivingTasksStore } from "@posthog/ui/features/sidebar/archivingTa
import { useSidebarStore } from "@posthog/ui/features/sidebar/sidebarStore";
import { useTaskSelectionStore } from "@posthog/ui/features/sidebar/taskSelectionStore";
import { usePinnedTasks } from "@posthog/ui/features/sidebar/usePinnedTasks";
import {
type TaskData,
useSidebarData,
} from "@posthog/ui/features/sidebar/useSidebarData";
import { useSidebarData } from "@posthog/ui/features/sidebar/useSidebarData";
import { useTaskViewed } from "@posthog/ui/features/sidebar/useTaskViewed";
import { useTaskContextMenu } from "@posthog/ui/features/tasks/useTaskContextMenu";
import { useRenameTask } from "@posthog/ui/features/tasks/useTaskMutations";
Expand All @@ -40,10 +38,6 @@ import { TasksHeader } from "./TasksHeader";

const log = logger.scope("sidebar-menu");

function isTaskActivelyRunning(task: TaskData): boolean {
return task.taskRunStatus === "in_progress" || task.isGenerating;
}

function SidebarMenuComponent() {
const hostClient = useHostTRPCClient();
const archiveCacheKeys = useArchiveCacheKeys();
Expand Down
Loading