perf(issues): narrow queued comment wake display reads (#17570)

Read only typed queue display inputs from saved wake payloads and only runtime mode from queued runs. Preserve complete rows for locked edits, discard, steering, and interruption.

Validation: 93 focused route and policy tests, full build and repository typecheck. PostgreSQL fixtures preserve identical queue responses and saved input with less than 4 KB of read values; restoring the full wake read fails at about 1.8 MB. Exact-head Greptile 5/5 (medium), all CI checks green, and zero unresolved comments.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip authored and GitHub committed 2026-10-25 00:41:14 -07:00
1 parent 7494b8dd4c
commit 50797ea03c
3 files changed
+59 -5

No files matched your search

+6
View File
@@ -1816,6 +1816,12 @@ dispatch with cancellation and execution, and re-exports the existing
public helpers and configuration-incomplete error class. Keep preparation policy
changes in this module and its tests.
Queued-comment display reads select only wake identity, queue state, typed comment
and interaction bindings, the displayed wait reason, and fresh-session flags.
They read only the queued run's runtime mode. Mutation locks retain complete
wake and run rows, so edits, ordering, interruption, and saved execution inputs
keep their existing write contract.
Run retrieval and session state are in `server/src/services/heartbeat/run-state.ts`.
It owns bounded run projections, database encoding checks, task session reads and
writes, explicit resumes, session compaction, and usage/billing helpers.
@@ -220,6 +220,38 @@ describeEmbeddedPostgres("issue queued-comment routes", () => {
} finally { capture.flush(); await observed.$client.end(); }
});
it.each(["deferred", "queued"])("reads only queue display inputs from large %s wake payloads", async state => {
const f = await seedQueue();
if (state === "queued") await promoteQueue(f);
const client = app(f.companyId);
const path = `/api/issues/${f.issueId}/queued-comments`;
const expected = await request(client).get(path).expect(200);
const [wake] = await db.select().from(agentWakeupRequests).where(eq(agentWakeupRequests.id, f.wakeId));
const payload = "saved-wake-input🙂".repeat(30_000);
const context = wake.payload?._paperclipWakeContext as Record<string, unknown>;
await db.update(agentWakeupRequests).set({ payload: {
...wake.payload, prompt: payload,
_paperclipWakeContext: { ...context, prompt: payload, nativeExecutionInput: { instructions: payload } },
} }).where(eq(agentWakeupRequests.id, f.wakeId));
await db.update(heartbeatRuns).set({ contextSnapshot: { issueId: f.issueId, prompt: payload },
runnerProfileJson: { instructions: payload }, resultJson: { output: payload },
}).where(eq(heartbeatRuns.companyId, f.companyId));
const [before] = await db.select().from(agentWakeupRequests).where(eq(agentWakeupRequests.id, f.wakeId));
const observed = createDb(tempDb!.connectionString), events: Array<Record<string, unknown>> = [], now = Date.now();
const capture = createDatabaseResponseCapture({ start: now - 100, end: now + 59_000 }, event => events.push(event));
installDatabaseResponseCapture(observed, { agentWakeupRequests, heartbeatRuns }, capture);
try {
const response = await request(app(f.companyId, "queue-owner", undefined, observed)).get(path).expect(200);
expect(response.body).toEqual(expected.body);
capture.flush();
const reads = events.filter(event => ["agent_wakeup_requests", "heartbeat_runs"].includes(String(event.table)) && event.operation === "select");
expect(reads.some(event => event.table === "agent_wakeup_requests")).toBe(true);
expect(reads.reduce((bytes, event) => bytes + Number(event.responseValueBytes), 0)).toBeLessThan(4096);
expect((await db.select().from(agentWakeupRequests).where(eq(agentWakeupRequests.id, f.wakeId)))[0]).toEqual(before);
await request(app(randomUUID(), "queue-owner", undefined, observed)).get(path).expect(404);
} finally { capture.flush(); await observed.$client.end(); }
});
it.each(["cancelled", "running"])("rejects a late Done from an interrupted %s task run at the write boundary", async status => {
const seeded = await seedQueue();
await db.update(heartbeatRuns).set({ status, resultJson: { executionCancellation: { state: "requested" } } })
+21 -5
View File
@@ -7287,9 +7287,9 @@ export function issueRoutes(
type IssueQueueWake = typeof agentWakeupRequests.$inferSelect;
type IssueQueueRun = typeof heartbeatRuns.$inferSelect;
type IssueQueueState = {
wake: IssueQueueWake;
wake: Pick<IssueQueueWake, "id" | "companyId" | "payload" | "status" | "runId">;
state: "deferred" | "queued";
queueRun: IssueQueueRun | null;
queueRun: Pick<IssueQueueRun, "runtimeMode"> | null;
};
async function findQueuedCommentWake(
@@ -7298,7 +7298,23 @@ export function issueRoutes(
): Promise<IssueQueueState | null> {
if (!issue.assigneeAgentId) return null;
const rows = await executor
.select()
.select({
id: agentWakeupRequests.id, companyId: agentWakeupRequests.companyId,
status: agentWakeupRequests.status, runId: agentWakeupRequests.runId,
payload: sql<Record<string, unknown>>`jsonb_build_object(
'issueId', ${agentWakeupRequests.payload}->'issueId',
'mutation', ${agentWakeupRequests.payload}->'mutation',
'interactionId', ${agentWakeupRequests.payload}->'interactionId',
'interactionStatus', ${agentWakeupRequests.payload}->'interactionStatus',
'externalChatContinuation', ${agentWakeupRequests.payload}->'externalChatContinuation',
'executionWait', jsonb_build_object(
'reason', ${agentWakeupRequests.payload}->'executionWait'->'reason',
'message', ${agentWakeupRequests.payload}->'executionWait'->'message'),
'_paperclipWakeContext', jsonb_build_object(
'wakeCommentIds', ${agentWakeupRequests.payload}->'_paperclipWakeContext'->'wakeCommentIds',
'forceFreshSession', ${agentWakeupRequests.payload}->'_paperclipWakeContext'->'forceFreshSession')
)`,
})
.from(agentWakeupRequests)
.where(
and(
@@ -7323,7 +7339,7 @@ export function issueRoutes(
}
if (!wake.runId) continue;
const queueRun = await executor
.select()
.select({ runtimeMode: heartbeatRuns.runtimeMode })
.from(heartbeatRuns)
.where(
and(
@@ -7344,7 +7360,7 @@ export function issueRoutes(
async function queueCommentsForWake(
executor: IssueQueueDb,
issueId: string,
wake: IssueQueueWake | null,
wake: Pick<IssueQueueWake, "companyId" | "payload"> | null,
) {
if (wake && queuedInteractionId(wake.payload)) {
const response = await readQueuedInteractionResponse(executor as Db, wake.companyId, issueId, wake.payload);