From 2a322fdac4e30bd6114415a8dcbe415911c9ee48 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Tue, 26 May 2026 10:17:55 +0100 Subject: [PATCH 1/3] Slim down the inbox "Create PR" prompt and auto-launch The Create PR button on an inbox report was inlining the entire researched summary into a single prompt and dumping the user back into TaskInput so they had to read, edit and submit it themselves. The wall of text made the task feel intimidating and slowed people down enough that they often dropped off before actually kicking it off. Mirror the Discuss flow: build a short, intent-only prompt that tells the agent to fetch the report through the inbox MCP tools, then create the task directly in auto mode and jump to it - same UX shape as Discuss, just for implementation instead of conversation. - new `buildCreatePrReportPrompt` util + tests for the short prompt shape - new `useCreatePrReport` hook that mirrors `useDiscussReport`, hardcoding `executionMode: "auto"` and `cloudRunSource: "signal_report"` - `ReportDetailPane` swaps `navigateToTaskInput` for the hook, shows a spinner while the task is being created, and disables the button while in-flight Generated-By: PostHog Code Task-Id: 4884e8d3-538d-4b19-9dc9-3b76a07df269 --- .../components/detail/ReportDetailPane.tsx | 30 ++- .../features/inbox/hooks/useCreatePrReport.ts | 197 ++++++++++++++++++ .../utils/buildCreatePrReportPrompt.test.ts | 36 ++++ .../inbox/utils/buildCreatePrReportPrompt.ts | 14 ++ 4 files changed, 261 insertions(+), 16 deletions(-) create mode 100644 apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts create mode 100644 apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts create mode 100644 apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts diff --git a/apps/code/src/renderer/features/inbox/components/detail/ReportDetailPane.tsx b/apps/code/src/renderer/features/inbox/components/detail/ReportDetailPane.tsx index 0f803c90a..bbbee97f0 100644 --- a/apps/code/src/renderer/features/inbox/components/detail/ReportDetailPane.tsx +++ b/apps/code/src/renderer/features/inbox/components/detail/ReportDetailPane.tsx @@ -50,7 +50,6 @@ import type { Task, } from "@shared/types"; import type { InboxReportActionProperties } from "@shared/types/analytics"; -import { useNavigationStore } from "@stores/navigationStore"; import { useQuery } from "@tanstack/react-query"; import { isMac } from "@utils/platform"; import { @@ -63,6 +62,7 @@ import { useState, } from "react"; import { toast } from "sonner"; +import { useCreatePrReport } from "../../hooks/useCreatePrReport"; import { useDiscussReport } from "../../hooks/useDiscussReport"; import { ReportImplementationPrLink } from "../utils/ReportImplementationPrLink"; import { SignalReportActionabilityBadge } from "../utils/SignalReportActionabilityBadge"; @@ -265,7 +265,6 @@ export function ReportDetailPane({ ); // ── Task creation ─────────────────────────────────────────────────────── - const { navigateToTaskInput } = useNavigationStore(); const { data: reportRepository } = useReportRepository(report.id); const trpcReact = useTRPC(); const { data: mostRecentRepo } = useQuery( @@ -360,22 +359,20 @@ export function ReportDetailPane({ [fireDetailAction], ); - const handleCreateImplementationTask = useCallback(() => { - if (!canCreateImplementationPr) return; + const { createPrReport, isCreatingPr } = useCreatePrReport({ + reportId: report.id, + reportTitle: report.title, + cloudRepository: effectiveCloudRepository, + }); + + const handleCreateImplementationTask = useCallback(async () => { + if (!canCreateImplementationPr || isCreatingPr) return; fireDetailAction("create_pr"); - navigateToTaskInput({ - initialPrompt: `Act on this signal report. Investigate the root cause, implement the fix, and open a PR if appropriate.\n\n${report.summary ?? ""}`, - initialCloudRepository: effectiveCloudRepository ?? undefined, - reportAssociation: { - reportId: report.id, - title: report.title ?? "Untitled signal", - }, - }); + await createPrReport(); }, [ canCreateImplementationPr, - navigateToTaskInput, - effectiveCloudRepository, - report, + isCreatingPr, + createPrReport, fireDetailAction, ]); @@ -598,9 +595,10 @@ export function ReportDetailPane({ size="1" variant="solid" className="gap-1 text-[12px]" + disabled={isCreatingPr} onClick={handleCreateImplementationTask} > - + {isCreatingPr ? : } Create PR diff --git a/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts b/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts new file mode 100644 index 000000000..9b5936596 --- /dev/null +++ b/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts @@ -0,0 +1,197 @@ +import { useAuthStateValue } from "@features/auth/hooks/authQueries"; +import { useSettingsStore } from "@features/settings/stores/settingsStore"; +import { useCreateTask } from "@features/tasks/hooks/useTasks"; +import { useUserRepositoryIntegration } from "@hooks/useIntegrations"; +import { get } from "@renderer/di/container"; +import { RENDERER_TOKENS } from "@renderer/di/tokens"; +import { trpcClient } from "@renderer/trpc/client"; +import { toast } from "@renderer/utils/toast"; +import { ANALYTICS_EVENTS } from "@shared/types/analytics"; +import { getCloudUrlFromRegion } from "@shared/utils/urls"; +import { useNavigationStore } from "@stores/navigationStore"; +import { track } from "@utils/analytics"; +import { logger } from "@utils/logger"; +import { useCallback, useState } from "react"; +import { toast as sonnerToast } from "sonner"; +import type { + TaskCreationInput, + TaskService, +} from "../../task-detail/service/service"; +import { buildCreatePrReportPrompt } from "../utils/buildCreatePrReportPrompt"; + +const log = logger.scope("create-pr-report"); + +interface UseCreatePrReportOptions { + reportId: string; + reportTitle: string | null; + cloudRepository: string | null; +} + +interface UseCreatePrReportReturn { + /** Create an auto-mode implementation task for the report and navigate to it on success. */ + createPrReport: () => Promise; + /** True while the task is being created. */ + isCreatingPr: boolean; +} + +async function resolveDefaultModel( + apiHost: string, + adapter: "claude" | "codex", +): Promise { + try { + const options = await trpcClient.agent.getPreviewConfigOptions.query({ + apiHost, + adapter, + }); + const modelOption = options.find( + (o) => o.id === "model" || o.category === "model", + ); + if (modelOption?.type === "select" && modelOption.currentValue) { + return modelOption.currentValue; + } + } catch (error) { + log.warn("Failed to resolve default model for Create PR", { + error, + adapter, + }); + } + return undefined; +} + +/** + * Create an implementation (PR) task directly from the inbox detail pane. + * + * Mirrors the Discuss flow: bypasses TaskInput so the user stays on the inbox + * until the task is ready, then jumps straight to the task detail page. The + * agent gets a short prompt that points it at the inbox MCP tools instead of + * inlining the entire report summary. + */ +export function useCreatePrReport({ + reportId, + reportTitle, + cloudRepository, +}: UseCreatePrReportOptions): UseCreatePrReportReturn { + const [isCreatingPr, setIsCreatingPr] = useState(false); + const { navigateToTask } = useNavigationStore(); + const { getUserIntegrationIdForRepo } = useUserRepositoryIntegration(); + const { invalidateTasks } = useCreateTask(); + const cloudRegion = useAuthStateValue((state) => state.cloudRegion); + + const createPrReport = useCallback(async () => { + if (isCreatingPr) return; + if (!cloudRepository) { + toast.error("Pick a cloud repository before creating a PR"); + return; + } + + const githubUserIntegrationId = + getUserIntegrationIdForRepo(cloudRepository); + if (!githubUserIntegrationId) { + toast.error("Connect a GitHub integration to create a PR"); + return; + } + + if (!cloudRegion) { + toast.error("Sign in to create a PR"); + return; + } + + setIsCreatingPr(true); + const toastId = toast.loading( + "Starting PR task...", + reportTitle ?? undefined, + ); + + const prompt = buildCreatePrReportPrompt({ + reportId, + isDevBuild: import.meta.env.DEV, + }); + + const settings = useSettingsStore.getState(); + const adapter = settings.lastUsedAdapter ?? "claude"; + const apiHost = getCloudUrlFromRegion(cloudRegion); + + const model = + settings.lastUsedModel ?? (await resolveDefaultModel(apiHost, adapter)); + + if (!model) { + sonnerToast.dismiss(toastId); + toast.error("Failed to start PR task", { + description: + "Couldn't resolve a default model. Open the task page once and pick a model, then try again.", + }); + setIsCreatingPr(false); + return; + } + + const input: TaskCreationInput = { + content: prompt, + taskDescription: prompt, + repository: cloudRepository, + githubUserIntegrationId, + workspaceMode: "cloud", + executionMode: "auto", + adapter, + model, + reasoningLevel: settings.lastUsedReasoningEffort ?? undefined, + cloudPrAuthorshipMode: "user", + cloudRunSource: "signal_report", + signalReportId: reportId, + }; + + try { + const taskService = get(RENDERER_TOKENS.TaskService); + const result = await taskService.createTask(input, (output) => { + invalidateTasks(output.task); + navigateToTask(output.task); + }); + + if (result.success) { + sonnerToast.dismiss(toastId); + track(ANALYTICS_EVENTS.TASK_CREATED, { + auto_run: true, + created_from: "command-menu", + repository_provider: "github", + workspace_mode: "cloud", + has_branch: false, + cloud_run_source: "signal_report", + cloud_pr_authorship_mode: "user", + adapter, + }); + } else { + sonnerToast.dismiss(toastId); + toast.error("Failed to start PR task", { + description: result.error, + }); + log.error("Create PR task creation failed", { + failedStep: result.failedStep, + error: result.error, + reportId, + reportTitle, + }); + } + } catch (error) { + sonnerToast.dismiss(toastId); + const description = + error instanceof Error ? error.message : "Unknown error"; + toast.error("Failed to start PR task", { description }); + log.error("Unexpected error during Create PR task creation", { + error, + reportId, + }); + } finally { + setIsCreatingPr(false); + } + }, [ + isCreatingPr, + cloudRepository, + cloudRegion, + reportId, + reportTitle, + getUserIntegrationIdForRepo, + invalidateTasks, + navigateToTask, + ]); + + return { createPrReport, isCreatingPr }; +} diff --git a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts new file mode 100644 index 000000000..1d4e00b98 --- /dev/null +++ b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; +import { buildCreatePrReportPrompt } from "./buildCreatePrReportPrompt"; + +describe("buildCreatePrReportPrompt", () => { + it("uses the production deeplink scheme outside dev builds", () => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild: false, + }); + expect(prompt).toContain("posthog-code://inbox/abc123"); + }); + + it("uses the dev deeplink scheme in dev builds", () => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild: true, + }); + expect(prompt).toContain("posthog-code-dev://inbox/abc123"); + }); + + it("references the inbox MCP tools so the agent fetches the detail itself", () => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild: false, + }); + expect(prompt).toContain("inbox MCP tools"); + }); + + it("asks the agent to open a PR", () => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild: false, + }); + expect(prompt).toMatch(/open a PR/i); + }); +}); diff --git a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts new file mode 100644 index 000000000..463c6deb1 --- /dev/null +++ b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts @@ -0,0 +1,14 @@ +import { getDeeplinkProtocol } from "@shared/deeplink"; + +interface BuildCreatePrReportPromptOptions { + reportId: string; + isDevBuild: boolean; +} + +export function buildCreatePrReportPrompt({ + reportId, + isDevBuild, +}: BuildCreatePrReportPromptOptions): string { + const reportLink = `${getDeeplinkProtocol(isDevBuild)}://inbox/${reportId}`; + return `Act on PostHog inbox report ${reportId} ([inbox item](${reportLink})). Use the inbox MCP tools to fetch the report, its signals, and any suggested reviewers; investigate the root cause; implement the fix; and open a PR.`; +} From a73a7c36fa1d4ba9a2382c045d4971a57000b499 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Tue, 26 May 2026 10:36:20 +0100 Subject: [PATCH 2/3] Extract resolveDefaultModel, parameterise scheme test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Greptile review on #2370. - Pull `resolveDefaultModel` into a shared util so the inbox Discuss and Create PR hooks aren't carrying identical copies of the preview-config lookup. Both hooks now import from `utils/resolveDefaultModel`. - Collapse the two prod/dev deeplink scheme tests for `buildCreatePrReportPrompt` into a single `it.each` block. Skipping the analytics `created_from: "command-menu"` → `"inbox_report"` suggestion: that label is a typed enum (`TaskCreatedFrom = "cli" | "command-menu"`), so adding a new value would touch the analytics schema and diverge from the Discuss flow this hook intentionally mirrors. Out of scope for the prompt-slim PR. Generated-By: PostHog Code Task-Id: 4884e8d3-538d-4b19-9dc9-3b76a07df269 --- .../features/inbox/hooks/useCreatePrReport.ts | 26 +------------- .../features/inbox/hooks/useDiscussReport.ts | 28 +-------------- .../utils/buildCreatePrReportPrompt.test.ts | 28 +++++++-------- .../inbox/utils/resolveDefaultModel.ts | 34 +++++++++++++++++++ 4 files changed, 49 insertions(+), 67 deletions(-) create mode 100644 apps/code/src/renderer/features/inbox/utils/resolveDefaultModel.ts diff --git a/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts b/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts index 9b5936596..5ebf3f564 100644 --- a/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts +++ b/apps/code/src/renderer/features/inbox/hooks/useCreatePrReport.ts @@ -4,7 +4,6 @@ import { useCreateTask } from "@features/tasks/hooks/useTasks"; import { useUserRepositoryIntegration } from "@hooks/useIntegrations"; import { get } from "@renderer/di/container"; import { RENDERER_TOKENS } from "@renderer/di/tokens"; -import { trpcClient } from "@renderer/trpc/client"; import { toast } from "@renderer/utils/toast"; import { ANALYTICS_EVENTS } from "@shared/types/analytics"; import { getCloudUrlFromRegion } from "@shared/utils/urls"; @@ -18,6 +17,7 @@ import type { TaskService, } from "../../task-detail/service/service"; import { buildCreatePrReportPrompt } from "../utils/buildCreatePrReportPrompt"; +import { resolveDefaultModel } from "../utils/resolveDefaultModel"; const log = logger.scope("create-pr-report"); @@ -34,30 +34,6 @@ interface UseCreatePrReportReturn { isCreatingPr: boolean; } -async function resolveDefaultModel( - apiHost: string, - adapter: "claude" | "codex", -): Promise { - try { - const options = await trpcClient.agent.getPreviewConfigOptions.query({ - apiHost, - adapter, - }); - const modelOption = options.find( - (o) => o.id === "model" || o.category === "model", - ); - if (modelOption?.type === "select" && modelOption.currentValue) { - return modelOption.currentValue; - } - } catch (error) { - log.warn("Failed to resolve default model for Create PR", { - error, - adapter, - }); - } - return undefined; -} - /** * Create an implementation (PR) task directly from the inbox detail pane. * diff --git a/apps/code/src/renderer/features/inbox/hooks/useDiscussReport.ts b/apps/code/src/renderer/features/inbox/hooks/useDiscussReport.ts index b81a1e28c..7fdd66cde 100644 --- a/apps/code/src/renderer/features/inbox/hooks/useDiscussReport.ts +++ b/apps/code/src/renderer/features/inbox/hooks/useDiscussReport.ts @@ -4,7 +4,6 @@ import { useCreateTask } from "@features/tasks/hooks/useTasks"; import { useUserRepositoryIntegration } from "@hooks/useIntegrations"; import { get } from "@renderer/di/container"; import { RENDERER_TOKENS } from "@renderer/di/tokens"; -import { trpcClient } from "@renderer/trpc/client"; import { toast } from "@renderer/utils/toast"; import { ANALYTICS_EVENTS } from "@shared/types/analytics"; import { getCloudUrlFromRegion } from "@shared/utils/urls"; @@ -18,6 +17,7 @@ import type { TaskService, } from "../../task-detail/service/service"; import { buildDiscussReportPrompt } from "../utils/buildDiscussReportPrompt"; +import { resolveDefaultModel } from "../utils/resolveDefaultModel"; const log = logger.scope("discuss-report"); @@ -34,32 +34,6 @@ interface UseDiscussReportReturn { isDiscussing: boolean; } -/** - * Resolve the default model for the given adapter via the preview-config - * tRPC query. Returns the server's `currentValue` for the `model` option, or - * undefined if the call fails or the option is missing. - */ -async function resolveDefaultModel( - apiHost: string, - adapter: "claude" | "codex", -): Promise { - try { - const options = await trpcClient.agent.getPreviewConfigOptions.query({ - apiHost, - adapter, - }); - const modelOption = options.find( - (o) => o.id === "model" || o.category === "model", - ); - if (modelOption?.type === "select" && modelOption.currentValue) { - return modelOption.currentValue; - } - } catch (error) { - log.warn("Failed to resolve default model for Discuss", { error, adapter }); - } - return undefined; -} - /** * Create a Discuss task directly from the inbox detail pane. * diff --git a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts index 1d4e00b98..a63394cc8 100644 --- a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts +++ b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts @@ -2,21 +2,19 @@ import { describe, expect, it } from "vitest"; import { buildCreatePrReportPrompt } from "./buildCreatePrReportPrompt"; describe("buildCreatePrReportPrompt", () => { - it("uses the production deeplink scheme outside dev builds", () => { - const prompt = buildCreatePrReportPrompt({ - reportId: "abc123", - isDevBuild: false, - }); - expect(prompt).toContain("posthog-code://inbox/abc123"); - }); - - it("uses the dev deeplink scheme in dev builds", () => { - const prompt = buildCreatePrReportPrompt({ - reportId: "abc123", - isDevBuild: true, - }); - expect(prompt).toContain("posthog-code-dev://inbox/abc123"); - }); + it.each([ + { isDevBuild: false, expectedScheme: "posthog-code" }, + { isDevBuild: true, expectedScheme: "posthog-code-dev" }, + ])( + "uses the $expectedScheme deeplink scheme when isDevBuild=$isDevBuild", + ({ isDevBuild, expectedScheme }) => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild, + }); + expect(prompt).toContain(`${expectedScheme}://inbox/abc123`); + }, + ); it("references the inbox MCP tools so the agent fetches the detail itself", () => { const prompt = buildCreatePrReportPrompt({ diff --git a/apps/code/src/renderer/features/inbox/utils/resolveDefaultModel.ts b/apps/code/src/renderer/features/inbox/utils/resolveDefaultModel.ts new file mode 100644 index 000000000..21690f976 --- /dev/null +++ b/apps/code/src/renderer/features/inbox/utils/resolveDefaultModel.ts @@ -0,0 +1,34 @@ +import { trpcClient } from "@renderer/trpc/client"; +import { logger } from "@utils/logger"; + +const log = logger.scope("resolve-default-model"); + +/** + * Resolve the default model for the given adapter via the preview-config + * tRPC query. Returns the server's `currentValue` for the `model` option, or + * undefined if the call fails or the option is missing. + * + * Used by inbox flows that create cloud tasks directly (Discuss, Create PR) + * without going through TaskInput — they need a model to pass to the saga + * and the user hasn't necessarily picked one yet. + */ +export async function resolveDefaultModel( + apiHost: string, + adapter: "claude" | "codex", +): Promise { + try { + const options = await trpcClient.agent.getPreviewConfigOptions.query({ + apiHost, + adapter, + }); + const modelOption = options.find( + (o) => o.id === "model" || o.category === "model", + ); + if (modelOption?.type === "select" && modelOption.currentValue) { + return modelOption.currentValue; + } + } catch (error) { + log.warn("Failed to resolve default model", { error, adapter }); + } + return undefined; +} From 6ebc9d88ff509f02cef967d139b12b028a6e4d31 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Tue, 26 May 2026 15:32:05 +0100 Subject: [PATCH 3/3] fix(inbox): tell agent to bail rather than guess if report fetch fails The slim Create PR / Discuss prompts no longer inline the report summary, so the agent depends on the inbox MCP returning the report. Add a guard clause so it stops and reports instead of proceeding on a hallucinated understanding when the fetch fails. --- .../inbox/utils/buildCreatePrReportPrompt.test.ts | 9 +++++++++ .../inbox/utils/buildCreatePrReportPrompt.ts | 2 +- .../inbox/utils/buildDiscussReportPrompt.test.ts | 14 ++++++++++++++ .../inbox/utils/buildDiscussReportPrompt.ts | 5 ++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts index a63394cc8..5087a137d 100644 --- a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts +++ b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.test.ts @@ -31,4 +31,13 @@ describe("buildCreatePrReportPrompt", () => { }); expect(prompt).toMatch(/open a PR/i); }); + + it("tells the agent to stop rather than guess if the report can't be fetched", () => { + const prompt = buildCreatePrReportPrompt({ + reportId: "abc123", + isDevBuild: false, + }); + expect(prompt).toMatch(/can't fetch the report/i); + expect(prompt).toMatch(/instead of guessing/i); + }); }); diff --git a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts index 463c6deb1..3e67772b0 100644 --- a/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts +++ b/apps/code/src/renderer/features/inbox/utils/buildCreatePrReportPrompt.ts @@ -10,5 +10,5 @@ export function buildCreatePrReportPrompt({ isDevBuild, }: BuildCreatePrReportPromptOptions): string { const reportLink = `${getDeeplinkProtocol(isDevBuild)}://inbox/${reportId}`; - return `Act on PostHog inbox report ${reportId} ([inbox item](${reportLink})). Use the inbox MCP tools to fetch the report, its signals, and any suggested reviewers; investigate the root cause; implement the fix; and open a PR.`; + return `Act on PostHog inbox report ${reportId} ([inbox item](${reportLink})). Use the inbox MCP tools to fetch the report, its signals, and any suggested reviewers; investigate the root cause; implement the fix; and open a PR. If you can't fetch the report, stop and report that instead of guessing what it contains.`; } diff --git a/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.test.ts b/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.test.ts index 389e0dadc..a6e078a37 100644 --- a/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.test.ts +++ b/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.test.ts @@ -44,4 +44,18 @@ describe("buildDiscussReportPrompt", () => { }); expect(prompt).toContain("brief readout"); }); + + it("tells the agent to say so rather than guess if the report can't be fetched", () => { + const withQuestion = buildDiscussReportPrompt({ + reportId: "abc123", + question: "Why is conversion dropping?", + isDevBuild: false, + }); + const withoutQuestion = buildDiscussReportPrompt({ + reportId: "abc123", + isDevBuild: false, + }); + expect(withQuestion).toMatch(/can't fetch the report/i); + expect(withoutQuestion).toMatch(/can't fetch the report/i); + }); }); diff --git a/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.ts b/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.ts index bb4361402..fe815ca8f 100644 --- a/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.ts +++ b/apps/code/src/renderer/features/inbox/utils/buildDiscussReportPrompt.ts @@ -14,7 +14,10 @@ export function buildDiscussReportPrompt({ const trimmedQuestion = question?.trim(); const reportLink = `${getDeeplinkProtocol(isDevBuild)}://inbox/${reportId}`; const intro = `Discuss PostHog inbox report ${reportId} ([inbox item](${reportLink})). Use the inbox MCP tools to fetch the report,`; - return trimmedQuestion + const guard = + " If you can't fetch the report, say so instead of guessing what it contains."; + const body = trimmedQuestion ? `${intro} then answer this first: ${trimmedQuestion}` : `${intro} then give me a brief readout and ask what I want to dig into.`; + return `${body}${guard}`; }