Conversation
| activity.kind, | ||
| activity.summary, | ||
| activity.payload_json AS "payload", | ||
| CASE |
There was a problem hiding this comment.
🟠 High Layers/ProjectionSnapshotQuery.ts:1372
Oversized pinned approval.requested and user-input.requested activities are returned without requestId (and without questions for user input), so the client cannot derive an actionable request and the provider turn remains blocked. The truncation branch replaces the entire payload with a generic marker; keep pinned unresolved-request payloads intact (or truncate while preserving the required request fields).
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts around line 1372:
Oversized pinned `approval.requested` and `user-input.requested` activities are returned without `requestId` (and without `questions` for user input), so the client cannot derive an actionable request and the provider turn remains blocked. The truncation branch replaces the entire payload with a generic marker; keep pinned unresolved-request payloads intact (or truncate while preserving the required request fields).
| ORDER BY sequence DESC, created_at DESC, activity_id DESC | ||
| ) AS recent_order, | ||
| MIN( | ||
| length(payload_json), |
There was a problem hiding this comment.
🟠 High Layers/ProjectionSnapshotQuery.ts:1046
length(payload_json) counts Unicode code points for SQLite TEXT, not UTF-8 bytes, so multi-byte JSON payloads bypass the 512 KiB per-payload cutoff and the 8 MiB cumulative budget; this can hydrate tens of MiB. Use a byte-length expression such as length(CAST(payload_json AS BLOB)) consistently for the cutoff, truncation marker, and cumulative budget.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts around line 1046:
`length(payload_json)` counts Unicode code points for SQLite `TEXT`, not UTF-8 bytes, so multi-byte JSON payloads bypass the 512 KiB per-payload cutoff and the 8 MiB cumulative budget; this can hydrate tens of MiB. Use a byte-length expression such as `length(CAST(payload_json AS BLOB))` consistently for the cutoff, truncation marker, and cumulative budget.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This production change alters thread-detail payloads and selectively omits persisted activities to enforce hydration limits across full and windowed reads. Unresolved high-severity concerns remain around preserving actionable request fields and correctly enforcing byte limits, so the runtime behavior requires human review. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
|
Note 🤖 GPT-6 Astra (preview) responding on behalf of Theo This was closed as part of an automated cleanup pass. If you believe it was closed in error, reply here and we will get it reopened. Closing this older-query implementation in favor of merged #9000, which projects client payloads in 25-row batches. This patch misses that client path and truncates fields required by pending requests. Its oversized-payload fixture remains available at f25c1ae, but it needs adaptation to the current query. This does not mean every large-payload memory failure is fixed. |
What Changed
Why
Severity: high (regular-use blocker).
Thread detail reads selected and JSON-decoded every persisted activity payload. Tool-heavy conversations can accumulate hundreds of megabytes or more of command output, so opening or refreshing an otherwise normal long-running conversation could exhaust Node's V8 heap. The backend would terminate and restart, disconnecting the client and dropping the in-flight conversation update.
The read model only needs a bounded recent timeline plus unresolved requests. Applying limits before payload decoding keeps thread detail usable without deleting durable history or hiding actionable requests.
Checklist