Preserve pending input order across steering sections

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-02 16:41:52 -05:00
1 parent 3728bb45ff
commit 603ad3726b
2 files changed
+18 -2

No files matched your search

@@ -34,12 +34,25 @@ import type {
TaskChatPlanDocumentItem,
TaskChatTurnItem,
} from "./task-chat-model";
import { latestPendingRuntimeRequest } from "./task-chat-model";
import { providerActivityPresentation } from "./task-chat-activity-presentation";
import { nativeRunEventsToTranscript } from "../transcript/native-run-events";
const TS = "2026-07-31T12:00:00.000Z";
describe("runtime requests across steering sections", () => {
it("selects the newer request when an older pending permission crosses steering", () => {
const older: TranscriptEntry = { kind: "runtime_request", ts: TS, requestId: "older-permission",
requestKind: "permission_approval", turnId: "provider-turn", requestType: "permission", status: "pending",
prompt: "Earlier write", choices: [{ key: "decline", label: "Deny" }], fields: [] };
const newer: TranscriptEntry = { ...older, ts: "2026-07-31T12:00:02.000Z", requestId: "newer-permission", prompt: "Later write" };
const options = { runId: "run-steering", running: true };
const context = runtimeRequestSegmentContext([older, newer], options);
const tail = reconcileSegmentRuntimeRequests(transcriptToTaskChatItems([newer], options), [newer], context, true);
expect(tail.map(item => item.id)).toEqual(["run-steering:runtime-request:older-permission", "run-steering:runtime-request:newer-permission"]);
expect(latestPendingRuntimeRequest(tail)?.requestId).toBe("newer-permission");
});
it.each(["pending", "resolved", "cancelled"] as const)("keeps one %s permission under whole-run authority", status => {
const request: TranscriptEntry = { kind: "runtime_request", ts: TS, requestId: "permission-1",
requestKind: "permission_approval", turnId: "provider-turn", requestType: "permission", status: "pending",
@@ -606,12 +606,15 @@ export function reconcileSegmentRuntimeRequests(
retained.add(item.id);
return [state.item];
});
const carried: TaskChatItem[] = [];
if (carryPending) {
for (const { item } of context.values()) {
if (item.status === "pending" && !retained.has(item.id)) result.push(item);
if (item.status === "pending" && !retained.has(item.id)) carried.push(item);
}
}
return result;
// A carried request predates this section. Keep newer requests last so the
// composer selects the latest input instead of reviving an older one.
return [...carried, ...result];
}
/**