feat(tasks): clear a finished cloud run's conversation without a sandbox - #76943
feat(tasks): clear a finished cloud run's conversation without a sandbox#76943haacked wants to merge 4 commits into
Conversation
🤖 CI report
|
| File | Size | Δ vs base |
|---|---|---|
render-query/src/render-query/render-query.js |
21.37 MiB | 🔺 +33.6 KiB (+0.2%) |
posthog-app/_parent/products/web_analytics/frontend/heatmaps/scenes/heatmap/HeatmapNewScene.js |
29.6 KiB | 🔺 +29.6 KiB (new) |
posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapNewScene.js |
removed | 🟢 -29.6 KiB (-100.0%) |
exporter/src/queries/schema.js |
1.10 MiB | 🔺 +16.6 KiB (+1.5%) |
posthog-app/src/queries/schema.js |
1.10 MiB | 🔺 +16.6 KiB (+1.5%) |
posthog-app/_parent/products/web_analytics/frontend/heatmaps/scenes/heatmap/HeatmapScene.js |
10.2 KiB | 🔺 +10.2 KiB (new) |
posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapScene.js |
removed | 🟢 -10.2 KiB (-100.0%) |
posthog-app/_parent/products/web_analytics/frontend/heatmaps/scenes/heatmaps/HeatmapsScene.js |
6.5 KiB | 🔺 +6.5 KiB (new) |
posthog-app/src/scenes/heatmaps/scenes/heatmaps/HeatmapsScene.js |
removed | 🟢 -6.5 KiB (-100.0%) |
posthog-app/_parent/products/web_analytics/frontend/heatmaps/scenes/heatmap/HeatmapRecordingScene.js |
4.0 KiB | 🔺 +4.0 KiB (new) |
posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapRecordingScene.js |
removed | 🟢 -4.0 KiB (-100.0%) |
posthog-app/src/scenes/billing/BillingSection.js |
19.1 KiB | 🟢 -3.3 KiB (-14.8%) |
posthog-app/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene.js |
161.2 KiB | 🔺 +3.3 KiB (+2.1%) |
posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.js |
100.3 KiB | 🔺 +2.4 KiB (+2.4%) |
posthog-app/src/scenes/experiments/Experiment.js |
243.1 KiB | 🟢 -1.6 KiB (-0.7%) |
posthog-app/src/scenes/AuthenticatedShell.js |
207.0 KiB | 🟢 -1.3 KiB (-0.6%) |
posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeatures.js |
6.8 KiB | 🔺 +1.2 KiB (+20.6%) |
posthog-app/_parent/products/tracing/frontend/TracingScene.js |
88.4 KiB | 🔺 +1.1 KiB (+1.3%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.26 MiB · 22 files | 🔺 +713 B (+0.1%) | ███░░░░░░░ 27.9% of 4.51 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
8.17 MiB · 3,046 files | 🟢 -3.8 KiB (-0.0%) | ████████░░ 84.2% of 9.71 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 285.5 KiB | ../node_modules/.pnpm/posthog-js@1.410.1/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 238.4 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 231.5 KiB | ../node_modules/.pnpm/posthog-js@1.410.1/node_modules/posthog-js/dist/module.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.0 KiB | src/lib/api.ts |
| 95.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.20 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.20 MiB · 17 files | 🔺 +1.4 KiB (+0.1%) | ████░░░░░░ 38.4% of 5.72 MiB |
| Deferred (lazy) | 2.08 MiB · 33 files | 🔺 +890 B (+0.0%) | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 723.0 KiB | dist/toolbar/toolbar-app-M7B2P2W4.css |
| 552.3 KiB | dist/toolbar/chunk-chunk-LINCPQWW.js |
| 484.6 KiB | dist/toolbar/chunk-chunk-5HONEO7J.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-PSGMVXK7.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-BIMPVI2A.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-QQAXO5G5.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-B5MOUYTE.js |
| 12.2 KiB | dist/toolbar/chunk-chunk-PIK3PADE.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +824.4 KiB (+0.1%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1394.78 MiB · 🔺 +824.4 KiB (+0.1%)
ℹ️ MCP UI apps size — 32 app(s), 17074.3 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 599.6 KB | 187.7 KB |
| action | 457.8 KB | 187.7 KB |
| action-list | 564.4 KB | 187.7 KB |
| cohort | 456.8 KB | 187.7 KB |
| cohort-list | 563.4 KB | 187.7 KB |
| email-template | 456.6 KB | 187.7 KB |
| error-details | 472.4 KB | 187.7 KB |
| error-issue | 457.5 KB | 187.7 KB |
| error-issue-list | 564.3 KB | 187.7 KB |
| experiment | 561.5 KB | 187.7 KB |
| experiment-list | 565.2 KB | 187.7 KB |
| experiment-results | 563.2 KB | 187.7 KB |
| feature-flag | 567.2 KB | 187.7 KB |
| feature-flag-list | 570.9 KB | 187.7 KB |
| feature-flag-testing | 461.0 KB | 187.7 KB |
| insight-actors | 562.2 KB | 187.7 KB |
| invite-email-preview | 456.0 KB | 187.7 KB |
| llm-costs | 559.5 KB | 187.7 KB |
| session-recording | 458.6 KB | 187.7 KB |
| session-summary | 463.9 KB | 187.7 KB |
| survey | 458.4 KB | 187.7 KB |
| survey-global-stats | 562.2 KB | 187.7 KB |
| survey-list | 565.1 KB | 187.7 KB |
| survey-stats | 562.2 KB | 187.7 KB |
| trace-span | 457.2 KB | 187.7 KB |
| trace-span-list | 564.3 KB | 187.7 KB |
| workflow | 457.1 KB | 187.7 KB |
| workflow-list | 563.7 KB | 187.7 KB |
| loops-review | 461.4 KB | 187.7 KB |
| query-results | 749.3 KB | 187.7 KB |
| render-ui | 830.0 KB | 187.7 KB |
| visual-review-snapshots | 461.6 KB | 187.7 KB |
⚠️ Backend coverage — 91.0% of changed backend lines covered — 6 uncovered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ██████████████████░░ 91.0% (63 / 69)
| File | Patch | Uncovered changed lines |
|---|---|---|
products/tasks/backend/presentation/views/api.py |
83.3% | 1405, 1412 |
products/tasks/backend/models.py |
86.4% | 2443–2444, 2446 |
products/tasks/backend/facade/api.py |
90.0% | 2438 |
🤖 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 31130976558 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
platform_features |
██░░░░░░░░░░░░░░░░░░ 12.1% |
7 / 58 |
batch_exports |
████████░░░░░░░░░░░░ 39.6% |
8,848 / 22,327 |
demo |
███████████░░░░░░░░░ 56.3% |
1,497 / 2,661 |
warehouse_sources_queue |
████████████░░░░░░░░ 59.2% |
148 / 250 |
data_tools |
██████████████░░░░░░ 70.0% |
63 / 90 |
tasks |
██████████████░░░░░░ 70.4% |
35,152 / 49,909 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
signals |
████████████████░░░░ 82.5% |
27,025 / 32,777 |
apm |
█████████████████░░░ 83.8% |
1,220 / 1,455 |
cdp |
█████████████████░░░ 84.2% |
3,914 / 4,646 |
notebooks |
█████████████████░░░ 86.4% |
8,029 / 9,296 |
data_modeling |
█████████████████░░░ 86.6% |
8,451 / 9,761 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
wizard |
█████████████████░░░ 86.7% |
1,090 / 1,257 |
managed_warehouse |
█████████████████░░░ 87.1% |
6,219 / 7,141 |
cohorts |
██████████████████░░ 87.6% |
6,482 / 7,400 |
data_warehouse |
██████████████████░░ 87.8% |
11,281 / 12,843 |
product_tours |
██████████████████░░ 87.9% |
1,303 / 1,482 |
business_knowledge |
██████████████████░░ 89.0% |
4,384 / 4,928 |
exports |
██████████████████░░ 89.2% |
7,429 / 8,328 |
engineering_analytics |
██████████████████░░ 89.2% |
6,716 / 7,527 |
dashboards |
██████████████████░░ 89.4% |
5,983 / 6,693 |
visual_review |
██████████████████░░ 89.5% |
5,870 / 6,558 |
alerts |
██████████████████░░ 90.3% |
4,482 / 4,966 |
conversations |
██████████████████░░ 90.4% |
18,026 / 19,932 |
canvas |
██████████████████░░ 90.6% |
2,075 / 2,291 |
links |
██████████████████░░ 90.6% |
183 / 202 |
streamlit_apps |
██████████████████░░ 90.7% |
2,630 / 2,901 |
error_tracking |
██████████████████░░ 91.1% |
11,153 / 12,243 |
stamphog |
██████████████████░░ 91.3% |
4,505 / 4,936 |
slack_app |
██████████████████░░ 91.6% |
10,627 / 11,602 |
marketing_analytics |
██████████████████░░ 92.1% |
13,388 / 14,539 |
managed_migrations |
███████████████████░ 92.6% |
1,556 / 1,681 |
notifications |
███████████████████░ 92.6% |
1,017 / 1,098 |
mcp_analytics |
███████████████████░ 92.7% |
3,810 / 4,112 |
ai_observability |
███████████████████░ 92.9% |
17,086 / 18,399 |
early_access_features |
███████████████████░ 92.9% |
1,347 / 1,450 |
mcp_store |
███████████████████░ 92.9% |
6,952 / 7,482 |
web_analytics |
███████████████████░ 93.1% |
15,963 / 17,154 |
surveys |
███████████████████░ 93.2% |
5,858 / 6,286 |
posthog_ai |
███████████████████░ 93.3% |
1,327 / 1,423 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
approvals |
███████████████████░ 93.5% |
3,491 / 3,734 |
product_analytics |
███████████████████░ 93.5% |
7,027 / 7,514 |
legal_documents |
███████████████████░ 93.8% |
1,628 / 1,736 |
endpoints |
███████████████████░ 94.3% |
8,771 / 9,306 |
workflows |
███████████████████░ 94.3% |
7,900 / 8,380 |
tracing |
███████████████████░ 94.5% |
2,678 / 2,834 |
review_hog |
███████████████████░ 94.6% |
8,246 / 8,715 |
skills |
███████████████████░ 94.8% |
3,478 / 3,669 |
messaging |
███████████████████░ 95.1% |
3,219 / 3,385 |
logs |
███████████████████░ 95.5% |
11,202 / 11,732 |
experiments |
███████████████████░ 95.7% |
27,557 / 28,806 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
revenue_analytics |
███████████████████░ 96.3% |
1,887 / 1,960 |
growth |
███████████████████░ 96.3% |
4,767 / 4,949 |
feature_flags |
███████████████████░ 96.4% |
17,580 / 18,235 |
replay_vision |
███████████████████░ 96.5% |
17,225 / 17,854 |
user_interviews |
███████████████████░ 96.5% |
2,638 / 2,734 |
access_control |
███████████████████░ 96.9% |
870 / 898 |
customer_analytics |
███████████████████░ 97.1% |
10,748 / 11,070 |
warehouse_sources |
███████████████████░ 97.4% |
381,535 / 391,701 |
data_catalog |
████████████████████ 97.9% |
2,677 / 2,734 |
analytics_platform |
████████████████████ 98.1% |
2,254 / 2,298 |
metrics |
████████████████████ 98.2% |
2,491 / 2,536 |
pulse |
████████████████████ 98.4% |
2,017 / 2,049 |
live_debugger |
████████████████████ 99.2% |
613 / 618 |
field_notes |
████████████████████ 99.4% |
158 / 159 |
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.
4fe0807 to
e1e3106
Compare
122eadb to
53d234b
Compare
A live run's /clear goes to its agent. A finished one has no agent, and
resuming into a whole new run just to clear a conversation that run would
rebuild from the log anyway is wasteful, so the boundary is recorded against
the finished run instead: POST runs/{id}/clear_conversation appends the typed
message plus a _posthog/conversation_cleared marker to its log. The logs
endpoint serves a resume chain concatenated, so both rehydration paths
already stop at the marker and the next run continues with an empty
conversation, its checkpoints and visible history intact.
Only for a finished run — an active one has an agent that owns the clear, and
a live writer on the same log object this read-modify-write append would
race, so it returns 409.
Both clients gate on the agent's conversationClear capability and fall back
to an ordinary new run when it is absent. An agent that predates the marker
ignores it on resume, so without the gate a user would see the boundary
rendered and believe a clear happened that never did.
The cloud thread renders the boundary and a "Clearing…" spinner, and /clear
is sent unwrapped: a context block would hide the command behind it, since
the agent reads the command off the front of the message.
Claude-Session: https://claude.ai/code/session_01HJQHhq27qXnKGj98x7UrXZ
Generated registration for the new endpoint, carried over from the original branch. Disabled like its siblings; the entry keeps the MCP codegen from drifting against the OpenAPI spec.
53d234b to
90a387c
Compare
🦔 ReviewHog reviewed this pull requestFound 0 must fix, 4 should fix, 3 consider. Published 7 findings (view the review). |
|
ReviewHog Alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏 |
There was a problem hiding this comment.
ReviewHog Report
Business logic
Issues: 2 issues
Files (4)
products/tasks/backend/models.pyproducts/tasks/backend/facade/api.pyproducts/tasks/backend/presentation/views/api.pyproducts/tasks/mcp/tools.yaml
What were the main changes
- TaskRun.emit_conversation_cleared() writes the typed /clear message plus a _posthog/conversation_cleared marker straight into a finished run's log, so resume rebuilds an empty conversation past it
- facade.clear_task_run_conversation gates on run.is_terminal, returning not_found/not_terminal outcomes instead of racing a live agent's log writer
- New POST runs/{id}/clear_conversation/ endpoint: 200 with the updated run DTO on success, 404 if missing, 409 if the run is still active (send /clear to its agent instead)
- MCP tools.yaml registers the new operation, disabled by default like other run-mutation endpoints
Changes
Issues: 5 issues
Files (3)
products/desktop/packages/api-client/src/posthog-client.tsproducts/desktop/packages/core/src/sessions/sessionEvents.tsproducts/desktop/packages/core/src/sessions/sessionService.ts
- Paint the /clear as a session/prompt request and tag the logged chunk so desktop renders the bubble live and after reload - Skip the append when the log already ends at the boundary, so repeats don't stack duplicate markers - Hold the run's row lock across the terminal check and append, so a concurrent resume can't flip the run active mid-write - Surface the 409 body's error detail instead of bare statusText - Log before the clear call, matching sibling cloud operations Generated-By: PostHog Code Task-Id: 2578f561-b94e-46ac-8546-d3368f5098bb
Prompt To Fix All With AI### Issue 1
products/posthog_ai/frontend/logics/runStreamLogic.ts:2087-2092
**Capability state remains stale**
When a resume chain contains an earlier run with `conversationClear` enabled and a later run whose agent does not advertise it, this sticky reducer remains true and authorizes the terminal-run clear endpoint. The UI then displays “Conversation cleared,” but the incapable agent ignores the boundary on resume and restores the full conversation.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(tasks): address review findings on t..." | Re-trigger Greptile |
…capability The reducer ratcheted permanently true, so after an agent rollback an earlier capable run kept authorizing the terminal-run clear endpoint and the UI painted a clear the next agent would ignore on resume. Follow the latest run_started's advertisement instead, matching the desktop client. Generated-By: PostHog Code Task-Id: 2578f561-b94e-46ac-8546-d3368f5098bb
🦔 Hogbox preview · ❌ build failedThe preview didn't come up for commit Previews are optional and never block merging. A failure here is often a hogland or tailnet hiccup rather than anything in your PR, so the check stays green and this comment is the status. |
|
React Doctor found 39 issues in 17 files · 2 errors & 37 warnings. Errors
37 warnings
Reviewed by React Doctor for commit |
There was a problem hiding this comment.
Pull request overview
Adds a dedicated “clear conversation” pathway for finished cloud task runs, avoiding the cost of spinning up a new sandbox just to execute /clear. This is implemented as a new backend endpoint that appends a /clear user turn plus a _posthog/conversation_cleared boundary marker to the run log, along with frontend + desktop rendering and capability-gated calling behavior.
Changes:
- Backend: add
POST /api/projects/:id/tasks/:task_id/runs/:run_id/clear_conversation/to record a/clearboundary only for terminal runs (409 for active runs). - Frontend (cloud thread): render
_posthog/conversation_cleared, handle “clearing”/“clearing_failed” status frames, and gate finished-run clears on the advertisedconversationClearcapability. - Desktop: add an API client method + SessionService shortcut to record the boundary and paint the cleared divider locally for finished cloud runs.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| products/tasks/mcp/tools.yaml | Registers the new clear-conversation operation in MCP tools (disabled by default). |
| products/tasks/frontend/generated/api.ts | Adds generated API client function for the clear-conversation endpoint. |
| products/tasks/backend/tests/test_api.py | Adds backend tests for boundary recording, dedupe, and active-run rejection. |
| products/tasks/backend/presentation/views/api.py | Adds the clear_conversation DRF action with OpenAPI annotations. |
| products/tasks/backend/models.py | Adds log-writing helpers to append a /clear turn + conversation boundary marker. |
| products/tasks/backend/facade/api.py | Adds facade method to lock/validate terminal status and append boundary to the log. |
| products/posthog_ai/frontend/types/wireTypes.ts | Extends notification param typings for conversation-cleared and status error fields. |
| products/posthog_ai/frontend/types/wireTypes.test.ts | Extends type contract tests for new notification shapes. |
| products/posthog_ai/frontend/types/streamTypes.ts | Adds conversation_cleared to ThreadItemType and clarifies errorMessage usage. |
| products/posthog_ai/frontend/logics/runStreamLogic.ts | Updates log folding to render the boundary divider and handle clearing statuses/errors; tracks conversationClearSupported. |
| products/posthog_ai/frontend/logics/runStreamLogic.test.ts | Adds logic tests for capability precedence and clear divider/status behavior. |
| products/posthog_ai/frontend/logics/runInteractionLogic.ts | Routes /clear on terminal runs to the new endpoint when capability is supported; avoids wrapping /clear in context. |
| products/posthog_ai/frontend/logics/runInteractionLogic.test.ts | Adds tests for terminal-run clear shortcut and capability-gated fallback behavior. |
| products/posthog_ai/frontend/components/ThreadView.tsx | Adds height estimate for the new conversation_cleared thread item type. |
| products/posthog_ai/frontend/components/ThreadRow.tsx | Renders ConversationClearedItem for the new thread item type. |
| products/posthog_ai/frontend/components/ThreadItems.tsx | Implements UI for “Clearing…” status and “Conversation cleared” divider. |
| products/desktop/packages/core/src/sessions/sessionServiceCloudClear.test.ts | Adds desktop tests for finished-run /clear boundary shortcut and fallback. |
| products/desktop/packages/core/src/sessions/sessionService.ts | Adds finished-run /clear shortcut to call backend boundary endpoint and paint events locally. |
| products/desktop/packages/core/src/sessions/sessionEvents.ts | Adds helper to create the local events sequence for a finished-run clear boundary. |
| products/desktop/packages/api-client/src/posthog-client.ts | Adds API client method to call the clear-conversation endpoint with typed error handling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import os | ||
| import re | ||
| import json | ||
| import uuid | ||
| import string | ||
| import secrets |
Problem
Stacked on #76457, which makes
/clearwork on a live cloud run.A finished run is the other half, and most cloud runs are finished when you look at them. There's no agent to send
/clearto, so the composer treated it as an ordinary message and started a whole new run: boot a sandbox, resume the conversation, clear it, idle. A full run's cost to clear a conversation the next run would rebuild from the log anyway.The cloud thread also rendered none of it.
_posthog/conversation_clearedfell throughfoldLogToThread's catch-all, and the twoclearingstatus frames showed up as rawStatus: clearingrows.Changes
POST runs/{id}/clear_conversationappends the typed message plus a_posthog/conversation_clearedmarker to a finished run's log. Thelogsendpoint already serves a resume chain concatenated, so both rehydration paths stop at the marker with no change: the next run continues the task with an empty conversation, and its checkpoints, artifacts, and visible history are untouched.Only for a finished run. An active one has an agent that owns the clear, and a live writer on the same log object this read-modify-write append would race, so it returns 409. Same reasoning as the note at
webhooks.py:245.Both clients (cloud composer, desktop session service) gate on the
conversationClearcapability from the stacked PR and fall back to an ordinary new run when it's absent.Note
This is why the stack has to land bottom-first. Merged alone, this PR can write boundaries no deployed agent knows how to read: the user sees the divider, believes the clear happened, and the next run resumes the full conversation. The gate makes that degrade to today's behavior instead, but the ordering is still the point.
The cloud thread renders the boundary and a "Clearing…" spinner mirroring compaction, and
/clearis sent unwrapped, since a context block would hide the command behind it and burn the task's one-shot context dedupe on a message nothing reads.How did you test this code?
Manually, against a local stack, with a seeded finished run:
I typed
/clearin the composer on a finished run and got the/clearbubble, the "Conversation cleared" divider, and the context ring at zero, through the real endpoint. I could not test the resume half or a live cloud run locally: both need a sandbox provider and a Temporal worker that a local stack doesn't have.Automated, all run locally:
test_api.pypackages/coresessionstypecheckclean repo-wide and on all four desktop packagesNew tests, and the regression each catches:
test_clear_conversation_records_the_boundary— the marker lands with the typed message ahead of it and carries nosessionId. If it ever gained one, resume would target a bogus session.test_clear_conversation_rejects_an_active_run(queued, in_progress) — 409 and an untouched log. Without the guard this appends into a log with a live writer.runInteractionLogic.test.tsandsessionServiceCloudClear.test.ts— with the capability absent, both writers start an ordinary run and never call the endpoint. This is the silent-wrong-behavior case, so it needs a test on each writer.Automatic notifications
Docs update
None needed. No user-facing docs cover
/clearyet.