feat(tasks): replace turn_complete thread writeback with pr_created artifact messages#72857
Conversation
|
Hey @k11kirky! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
products/tasks/backend/facade/api.py:5501-5506
**PR Deduplication Races**
The agent-output path and GitHub webhook can both pass this `exists()` check before either creates its message. Because there is no matching database uniqueness constraint or lock around the check-and-create sequence, the same PR can appear twice in the task thread.
### Issue 2 of 2
products/tasks/backend/facade/api.py:5261-5263
**Legacy Mentions Target Hidden Messages**
Legacy `turn_complete` messages created mention records for task creators, but this filter only hides the messages from the thread API. Those records remain in the separate mentions feed, so opening an existing notification leads to a thread where the referenced message is missing.
Reviews (1): Last reviewed commit: "feat(tasks): replace turn_complete threa..." | Re-trigger Greptile |
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 2 · PR risk: 0/10 |
tatoalo
left a comment
There was a problem hiding this comment.
Could we ensure the announcement even when pr_url is already populated? _record_run_output_field returns False and webhook retries can never repair the missing artifact. It would be safer to idempotently ensure the artifact whenever the persisted URL matches this webhooks one.
Agree also on greptile + veria points, thanks for this!
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
products/tasks/backend/facade/api.py |
94.4% | 5360, 5405 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 30046846386 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
tasks |
██████████████░░░░░░ 69.4% |
30,037 / 43,278 |
signals |
████████████████░░░░ 79.9% |
21,906 / 27,415 |
cdp |
████████████████░░░░ 81.0% |
3,144 / 3,881 |
data_modeling |
█████████████████░░░ 82.7% |
5,547 / 6,708 |
notebooks |
█████████████████░░░ 85.3% |
7,275 / 8,531 |
agent_platform |
█████████████████░░░ 86.4% |
3,807 / 4,405 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
cohorts |
██████████████████░░ 87.8% |
4,488 / 5,114 |
product_tours |
██████████████████░░ 87.9% |
1,303 / 1,482 |
exports |
██████████████████░░ 88.4% |
6,949 / 7,861 |
data_warehouse |
██████████████████░░ 88.9% |
11,887 / 13,378 |
conversations |
██████████████████░░ 89.3% |
16,834 / 18,848 |
engineering_analytics |
██████████████████░░ 89.4% |
6,386 / 7,145 |
dashboards |
██████████████████░░ 89.4% |
5,983 / 6,693 |
error_tracking |
██████████████████░░ 89.7% |
10,174 / 11,342 |
alerts |
██████████████████░░ 89.9% |
4,054 / 4,508 |
early_access_features |
██████████████████░░ 90.1% |
1,031 / 1,144 |
mcp_analytics |
██████████████████░░ 90.1% |
2,763 / 3,065 |
streamlit_apps |
██████████████████░░ 90.4% |
2,501 / 2,767 |
slack_app |
██████████████████░░ 90.7% |
9,028 / 9,951 |
marketing_analytics |
██████████████████░░ 91.0% |
11,792 / 12,964 |
stamphog |
██████████████████░░ 91.1% |
4,056 / 4,450 |
product_analytics |
███████████████████░ 92.7% |
5,811 / 6,268 |
ai_observability |
███████████████████░ 92.7% |
14,995 / 16,168 |
surveys |
███████████████████░ 93.0% |
5,730 / 6,163 |
web_analytics |
███████████████████░ 93.1% |
14,398 / 15,461 |
posthog_ai |
███████████████████░ 93.2% |
1,326 / 1,422 |
approvals |
███████████████████░ 93.3% |
3,437 / 3,682 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
workflows |
███████████████████░ 93.6% |
6,390 / 6,826 |
endpoints |
███████████████████░ 94.1% |
8,640 / 9,177 |
revenue_analytics |
███████████████████░ 94.6% |
3,651 / 3,858 |
review_hog |
███████████████████░ 94.7% |
6,814 / 7,199 |
skills |
███████████████████░ 94.7% |
3,086 / 3,258 |
logs |
███████████████████░ 95.4% |
9,935 / 10,416 |
experiments |
███████████████████░ 95.7% |
25,036 / 26,159 |
replay_vision |
███████████████████░ 96.2% |
15,170 / 15,774 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
feature_flags |
███████████████████░ 96.5% |
17,110 / 17,734 |
user_interviews |
███████████████████░ 96.5% |
2,638 / 2,734 |
customer_analytics |
███████████████████░ 97.1% |
9,047 / 9,317 |
warehouse_sources |
███████████████████░ 97.1% |
330,211 / 339,939 |
data_catalog |
███████████████████░ 97.4% |
2,367 / 2,429 |
pulse |
████████████████████ 98.4% |
2,017 / 2,049 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
Pull Request is not mergeable
7b6a642 to
0903d32
Compare
|
🔀 Tried to auto-resolve conflicts with I won't retry until the branch or master moves. |
…rtifact messages Task threads become a human-to-human surface with artifact announcements. The sandbox event relay no longer posts the agent's closing turn message into the thread, legacy turn_complete rows are excluded from the thread listing, and a pr_created agent message (deduped per PR URL) is now emitted when a run's pull request is recorded — from the agent-output paths and the GitHub webhook backstop — joining the existing canvas_created announcement. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
…unsafe URLs Address review findings: lock the task row so the agent-output path and webhook backstop can't both pass the pr_created dedupe check, reject pr_url values that aren't plain http(s) URLs before embedding them in the markdown message, and exclude legacy turn_complete mention rows from the mentions feed now that their messages are hidden from threads. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
Every task has a thread panel, so PR artifact announcements no longer require the task to be filed in a channel (canvas_created already behaved this way). Each remaining skip path (unsafe URL, missing creator, flag off) now logs its reason so a missing announcement is diagnosable. Adds end-to-end tests through update_task_run and set_task_run_output — the paths the agent actually uses to attach a PR. Generated-By: PostHog Code Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
Generated-By: PostHog Code Task-Id: 3afd10d7-2202-4615-b3c8-43d7373766b4
035b802 to
3049ff4
Compare
Problem
Task threads (the PostHog Code thread panel) mixed agent turn writebacks with human conversation. Threads should be a human-to-human surface, with the agent represented by the artifacts it produced. Canvases already announce themselves (
canvas_created), but pull requests never did — and every background turn ended with aturn_completeagent message in the thread.Changes
post_turn_complete_thread_updateand its call from the sandbox event relay (plus the now-dead final-message tracking in the relay loop). Background runs no longer write the agent's closing message into the thread.list_thread_messagesexcludes legacyturn_completerows so previously written turn messages don't resurface in clients.post_pr_created_thread_update: when a run's PR URL is recorded, an agent artifact message (event="pr_created",payload.pr_url, content[owner/repo#N](url) has been opened) lands in the task thread. Called from the run output paths (set_task_run_output,update_task_run) and the GitHub webhook backstop (_record_run_pr_url), deduped per PR URL via the task's existingpr_createdrows. Same feature-flag and channel guards as the other agent thread updates.The client side (rendering
pr_created/canvas_createdas artifact rows and dropping agent turn/prompt rows) is PostHog/code#3694.How did you test this code?
Red/green: rewrote
products/tasks/backend/tests/test_thread_updates.pyfirst (failing on the missing function), then implemented. Tests I (Claude) actually ran locally, all green:test_thread_updates(13 tests): pr_created content/payload, per-URL dedupe, distinct-PR handling, flag/channel/creator skip guards, canvas_created regression, turn_complete exclusion from listingtest_channels_api+test_webhooks(100 tests)test_facadetest_relay_sandbox_events(53 passed; one pre-existing test errored in my sandbox because the persons-DB sqlx fixture isn't available there — unrelated to this diff)ruff check/ruff formatcleanAutomatic notifications
Docs update
🤖 Agent context
Autonomy: Fully autonomous
Authored by Claude (PostHog Code cloud task) together with the paired client PR. Followed red-green testing: wrote the failing tests before each implementation change. Chose DB-backed dedupe (existing
pr_createdrows per URL) over a Redis cooldown since the agent-output path and webhook backstop can fire arbitrarily far apart.Created with PostHog Code