Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.
Closed
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: 2 additions & 0 deletions apps/mobile/src/app/inbox/[...id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ export default function ReportDetailScreen() {
prompt,
...(reportRepo ? { repo: reportRepo } : {}),
signalReport: report.id,
signalReportRelationship: "implementation",
},
});
},
Expand Down Expand Up @@ -374,6 +375,7 @@ export default function ReportDetailScreen() {
prompt,
...(reportRepo ? { repo: reportRepo } : {}),
signalReport: report.id,
signalReportRelationship: "discussion",
},
});
},
Expand Down
22 changes: 13 additions & 9 deletions apps/mobile/src/app/task/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ export default function NewTaskScreen() {
prompt: initialPrompt,
repo: initialRepo,
signalReport,
signalReportRelationship,
} = useLocalSearchParams<{
prompt?: string;
repo?: string;
signalReport?: string;
signalReportRelationship?: "implementation" | "discussion";
}>();
const router = useRouter();
const themeColors = useThemeColors();
Expand Down Expand Up @@ -320,7 +322,7 @@ export default function NewTaskScreen() {
: `Attached ${attachments.length} files`);

const client = getPostHogApiClient();
const task = await client.createTask({
const taskOptions = {
description: descriptionText,
title: descriptionText.slice(0, 100),
repository: selection.repository ?? undefined,
Expand All @@ -329,14 +331,15 @@ export default function NewTaskScreen() {
// UUID the API expects. The backend also auto-resolves this from the
// repository for user-created tasks, so it's a best-effort hint.
github_user_integration: getUserIntegrationId(selection.integrationId),
...(signalReport
? {
origin_product: "signal_report",
signal_report: signalReport,
signal_report_task_relationship: "implementation",
}
: {}),
} as CreateTaskOptions);
};
const task = signalReport
? await client.createSignalReportTask({
...taskOptions,
signal_report: signalReport,
signal_report_task_relationship:
signalReportRelationship ?? "implementation",
})
: await client.createTask(taskOptions as CreateTaskOptions);

pendingTaskPromptStoreApi.move(pendingKey, task.id);
currentPendingKey = task.id;
Expand Down Expand Up @@ -387,6 +390,7 @@ export default function NewTaskScreen() {
router,
selection,
signalReport,
signalReportRelationship,
getUserIntegrationId,
setComposerConfig,
]);
Expand Down
10 changes: 3 additions & 7 deletions apps/mobile/src/features/inbox/components/TinderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ import { MarkdownText } from "@/features/chat/components/MarkdownText";
import { usePreferencesStore } from "@/features/preferences/stores/preferencesStore";
import { getModelConfigOption } from "@/features/tasks/composer/options";
import { useCloudTaskConfigOptions } from "@/features/tasks/hooks/useCloudTaskConfigOptions";
import type {
CreateTaskOptions,
RepositoryOption,
} from "@/features/tasks/types";
import type { RepositoryOption } from "@/features/tasks/types";
import {
ANALYTICS_EVENTS,
computeReportAgeHours,
Expand Down Expand Up @@ -246,15 +243,14 @@ export function TinderView({
// 3. Create the task
const prompt = `Act on this signal report. Investigate the root cause, implement the fix, and open a PR if appropriate.\n\n${report.summary ?? ""}`;
const client = getPostHogApiClient();
const task = await client.createTask({
const task = await client.createSignalReportTask({
description: prompt,
title: prompt.slice(0, 255),
repository: match?.repository ?? repo ?? undefined,
github_integration: match?.integrationId ?? undefined,
origin_product: "signal_report",
signal_report: report.id,
signal_report_task_relationship: "implementation",
} as CreateTaskOptions);
});

// 4. Run it
await client.runTaskInCloud(task.id, undefined, {
Expand Down
33 changes: 33 additions & 0 deletions packages/api-client/src/posthog-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2642,6 +2642,39 @@ export class PostHogAPIClient {
return normalizeTaskResponse(data, { teamId });
}

async createSignalReportTask(
options: Record<string, unknown> & {
description: string;
signal_report: string;
signal_report_task_relationship: "implementation" | "discussion";
},
): Promise<Task> {
const teamId = await this.getTeamId();
const path = `/api/projects/${teamId}/tasks/signal_report/`;
const response = await this.api.fetcher.fetch({
method: "post",
path,
url: new URL(`${this.api.baseUrl}${path}`),
overrides: { body: JSON.stringify(options) },
throwOnStatusError: false,
});
if (response.status === 404) {
return this.createTask({
...options,
origin_product: "signal_report",
} as Parameters<PostHogAPIClient["createTask"]>[0]);
}
if (!response.ok) {
throw new Error(
`Failed to create signal report task: ${response.statusText}`,
);
}
return normalizeTaskResponse(
(await response.json()) as Parameters<typeof normalizeTaskResponse>[0],
{ teamId },
);
}

async updateTask(
taskId: string,
updates: Partial<Schemas.Task>,
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/inbox/reportTaskCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface BuildSignalReportTaskInput {
model: string;
reasoningLevel?: string;
baseBranch?: string | null;
relationship: "implementation" | "discussion";
}

/** Build the `TaskCreationInput` for an inbox direct-create (Discuss / Create-PR) flow. */
Expand All @@ -91,6 +92,7 @@ export function buildSignalReportTaskInput(
model,
reasoningLevel,
baseBranch,
relationship,
} = args;
return {
content: prompt,
Expand All @@ -106,5 +108,6 @@ export function buildSignalReportTaskInput(
cloudPrAuthorshipMode: "user",
cloudRunSource: "signal_report",
signalReportId: reportId,
signalReportTaskRelationship: relationship,
};
}
1 change: 1 addition & 0 deletions packages/core/src/inbox/signalReportTaskService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export class SignalReportTaskService {
model,
reasoningLevel: input.reasoningLevel,
baseBranch: input.baseBranch,
relationship: input.kind === "discuss" ? "discussion" : "implementation",
});

let result: CreateTaskResult;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/task-detail/taskCreationApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface TaskCreationApiClient {
getTask(taskId: string): Promise<Task>;
getTaskRun(taskId: string, runId: string): Promise<TaskRun>;
createTask(options: Record<string, unknown>): Promise<unknown>;
createSignalReportTask(options: Record<string, unknown>): Promise<unknown>;
deleteTask(taskId: string): Promise<void>;
createTaskRun(
taskId: string,
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/task-detail/taskCreationSaga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function makeSaga(
return new TaskCreationSaga({
posthogClient: {
createTask: vi.fn(),
createSignalReportTask: vi.fn(),
deleteTask: vi.fn(),
getTask: vi.fn(),
createTaskRun: vi.fn(),
Expand Down Expand Up @@ -943,11 +944,13 @@ describe("TaskCreationSaga", () => {
latest_run: createRun(),
});
const createTaskMock = vi.fn().mockResolvedValue(createdTask);
const createSignalReportTaskMock = vi.fn().mockResolvedValue(createdTask);
const createTaskRunMock = vi.fn().mockResolvedValue(createRun());
const startTaskRunMock = vi.fn().mockResolvedValue(startedTask);

const saga = makeSaga({
createTask: createTaskMock,
createSignalReportTask: createSignalReportTaskMock,
createTaskRun: createTaskRunMock,
startTaskRun: startTaskRunMock,
});
Expand All @@ -959,15 +962,18 @@ describe("TaskCreationSaga", () => {
branch: "main",
cloudRunSource: "signal_report",
signalReportId: "report-123",
signalReportTaskRelationship: "implementation",
githubIntegrationId: 123,
});

expect(result.success).toBe(true);
expect(createTaskMock).toHaveBeenCalledWith(
expect(createTaskMock).not.toHaveBeenCalled();
expect(createSignalReportTaskMock).toHaveBeenCalledWith(
expect.objectContaining({
github_integration: 123,
github_user_integration: undefined,
origin_product: "signal_report",
origin_product: undefined,
signal_report_task_relationship: "implementation",
}),
);
expect(createTaskRunMock).toHaveBeenCalledWith(
Expand Down
15 changes: 9 additions & 6 deletions packages/core/src/task-detail/taskCreationSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,12 @@ export class TaskCreationSaga extends Saga<
const description = input.taskDescription ?? input.content ?? "";
const canActivateWarmRun =
input.runtime !== "pi" && !warmPayload?.suppressWarmReuse;
const result = await this.deps.posthogClient.createTask({
const createTask = input.signalReportId
? this.deps.posthogClient.createSignalReportTask.bind(
this.deps.posthogClient,
)
: this.deps.posthogClient.createTask.bind(this.deps.posthogClient);
const result = await createTask({
description,
repository: repository ?? undefined,
github_integration:
Expand All @@ -803,11 +808,7 @@ export class TaskCreationSaga extends Saga<
input.cloudRunSource !== "signal_report"
? input.githubUserIntegrationId
: undefined,
origin_product: input.signalReportId
? "signal_report"
: "user_created",
// The server associates the task with the report and records the implementation
// task_run artefact — no relationship label is sent (associations are unlabelled).
origin_product: input.signalReportId ? undefined : "user_created",
branch:
input.workspaceMode === "cloud" && canActivateWarmRun
? (input.branch ?? null)
Expand Down Expand Up @@ -839,6 +840,8 @@ export class TaskCreationSaga extends Saga<
? input.customImageId
: undefined,
signal_report: input.signalReportId ?? undefined,
signal_report_task_relationship:
input.signalReportTaskRelationship ?? undefined,
channel: input.channelId ?? undefined,
runtime: input.runtime ?? "acp",
pending_user_message: warmPayload?.pendingUserMessage,
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/task-creation-domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface TaskCreationInput {
*/
cloudRtkEnabled?: boolean;
signalReportId?: string;
signalReportTaskRelationship?: "implementation" | "discussion";
additionalDirectories?: string[];
/**
* CONTEXT.md of the channel a task was created in, if any. Appended to the
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/features/inbox/hooks/useCreatePrReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export function useCreatePrReport({
cloudPrAuthorshipMode: "user",
cloudRunSource: "signal_report",
signalReportId: reportId,
signalReportTaskRelationship: "implementation",
};
},
[baseBranchOverrides, reportId, cloudRegion, projectId],
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/features/inbox/hooks/useDiscussReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export function useDiscussReport({
cloudPrAuthorshipMode: "user",
cloudRunSource: "signal_report",
signalReportId: reportId,
signalReportTaskRelationship: "discussion",
};
},
[reportId, reportTitle],
Expand Down
Loading