Skip to content

fix(sessions): name tasks from pasted text-file contents#2850

Open
fercgomes wants to merge 1 commit into
mainfrom
posthog-code/title-from-pasted-text-content
Open

fix(sessions): name tasks from pasted text-file contents#2850
fercgomes wants to merge 1 commit into
mainfrom
posthog-code/title-from-pasted-text-content

Conversation

@fercgomes

Copy link
Copy Markdown
Contributor

Problem

When you paste a prompt into PHCode it gets auto-converted to a pasted-text.txt attachment with no typed text, so the only signal for naming the task is the file's contents. The name generator wasn't reading them, so the task defaulted to Untitled.

Tracing the flow, the breakage is specific to cloud tasks:

  • Local tasks already work — the prompt event carries the <file path="…"/> tag inline, which the title generator reads.
  • Cloud tasks were broken — by the time the generator runs, the original local path is gone:
    • the stored description is reduced to Attached files: pasted-text.txt (no path), and
    • the echoed prompt event points at the remote sandbox path (file:///workspace/.posthog/attachments/…), which can't be read on the user's machine.

The local path only exists at submit time, before the file is uploaded as a cloud artifact — so the generator had only the filename and produced Untitled.

Fix

  1. titleAttachmentStore.ts (new) — small UI store that stashes the prompt's local attachment paths keyed by task id.
  2. useTaskCreation.ts — on task creation, stash those local paths for the new task id.
  3. useChatTitleGenerator.ts — read the stashed paths, hand them to the title generator, and clear them once a title is produced.
  4. titleGeneratorService.ts — widened the Attached files: matcher so the 1. [Attached files: …] form (produced when titling from prompts) is recognized as "no real text", falling through to the file contents.

The generator already truncates to 500 chars, skips binary files, and ignores attachments when real text is typed — so normal prompts are unaffected. This also makes the local path more robust (it now gets the explicit path too).

Tests

  • titleGeneratorService.test.ts — cases for the cloud description form (Attached files: …) and the numbered prompt-list form, plus a guard that typed text still wins over attachments.
  • useChatTitleGenerator.test.ts — a cloud-style case asserting stashed local paths are passed through and cleared after naming; updated existing assertions for the new arg.

Verification

Typecheck, Biome lint (incl. noRestrictedImports), and a full pnpm build pass; sessions + task-detail suites green (435 tests). Did not run a live cloud end-to-end (needs auth + cloud backend + a real LLM call) — covered by unit tests instead.

Known limitation

If the app reloads in the few seconds between submitting and the title generating, the in-memory stash is lost and the title falls back to the attachment summary (same as other in-memory optimistic state). Can persist it if desired.

When a prompt is pasted it is auto-converted to a `pasted-text.txt`
attachment with no typed text, so the task title must come from the
file's contents. This worked for local tasks (the prompt event carries
the `<file .../>` path inline) but not for cloud tasks: by the time the
title generator runs, the original local path is gone — the stored
description is reduced to `Attached files: <name>`, and the echoed
prompt event points at the remote sandbox path
(`file:///workspace/.posthog/attachments/...`), which is not readable
locally. The only place the local path exists is at submit time, before
the file is uploaded as an artifact, so the generator had nothing but
the filename and produced "Untitled".

Stash the prompt's local attachment paths at creation time (keyed by
task id), hand them to the title generator so it reads the file
contents, and clear them once a title is produced. Also widen the
attachment-summary matcher so the `1. [Attached files: ...]` form
(produced when titling from prompts) is treated as "no real text",
falling through to the file contents. Typed-text prompts are
unaffected — attachments are only read when there is no real text.

Generated-By: PostHog Code
Task-Id: 931c5770-c4d5-49d7-92d5-4e73b824e75a
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 1f19787.

@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(sessions): name tasks from pasted te..." | Re-trigger Greptile

Comment on lines +28 to +43
export const useTitleAttachmentStore = create<TitleAttachmentStore>(
(set, get) => ({
byTaskId: {},
set: (taskId, filePaths) =>
set((state) => ({
byTaskId: { ...state.byTaskId, [taskId]: filePaths },
})),
get: (taskId) => get().byTaskId[taskId],
clear: (taskId) =>
set((state) => {
if (!(taskId in state.byTaskId)) return state;
const { [taskId]: _removed, ...rest } = state.byTaskId;
return { byTaskId: rest };
}),
}),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unused React hook export

useTitleAttachmentStore is exported but never imported anywhere in the codebase (confirmed: only appears in its own file). The analogous usePendingTaskPromptStore in pendingTaskPromptStore.ts is at least wrapped by a usePendingTaskPrompt helper that consumes it; there is no equivalent usage here. Per the simplicity rule of no superfluous parts, this export can be dropped — titleAttachmentStoreApi is sufficient for all current call sites.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 104 to +108
const result = await titleGenerator.generateTitleAndSummary(content);
if (result) {
// The seed is consumed once a title has been produced; drop it so the
// map doesn't grow across a long-lived session.
titleAttachmentStoreApi.clear(taskId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Stash not cleared when LLM returns null

titleAttachmentStoreApi.clear(taskId) is only called inside if (result), so when generateTitleAndSummary returns null (on error or empty output), the stash entry survives. In the shouldGenerateFromTaskDescription path, initialDescriptionHandled is unconditionally set to true in the finally block, which prevents any description-path retry. The stash therefore stays populated for the rest of the session without any mechanism to consume or evict it other than the next prompt-based generation or a reload. This is acknowledged as best-effort, but moving the clear call to the finally block (only for the description path, not if a retry on prompts is still wanted) would make the lifecycle explicit.

@fercgomes fercgomes marked this pull request as ready for review June 22, 2026 23:13
@fercgomes fercgomes requested review from charlesvien and tatoalo June 22, 2026 23:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant