Skip to content

Commit 63ef59e

Browse files
committed
Fix issue where some approval requests were not appearing
1 parent 1c99cbf commit 63ef59e

File tree

2 files changed

+76
-23
lines changed

2 files changed

+76
-23
lines changed

apps/web/src/App.tsx

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,14 @@ function isPlanModeOption(mode: {
636636
);
637637
}
638638

639+
function buildModeSignature(
640+
modeKey: string,
641+
modelId: string,
642+
effort: string,
643+
): string {
644+
return `${modeKey}|${modelId}|${effort}`;
645+
}
646+
639647
function getConversationStateUpdatedAt(
640648
state: NonNullable<ReadThreadResponse["thread"]> | null | undefined,
641649
): number {
@@ -645,14 +653,6 @@ function getConversationStateUpdatedAt(
645653
return state.updatedAt;
646654
}
647655

648-
function buildModeSignature(
649-
modeKey: string,
650-
modelId: string,
651-
effort: string,
652-
): string {
653-
return `${modeKey}|${modelId}|${effort}`;
654-
}
655-
656656
function buildApprovalResponse(
657657
request: PendingApprovalRequest,
658658
action: "approve" | "deny",
@@ -1329,23 +1329,10 @@ export function App(): React.JSX.Element {
13291329
const requestSourceState = useMemo(() => {
13301330
const liveConversationState = liveState?.conversationState ?? null;
13311331
const readConversationState = readThreadState?.thread ?? null;
1332-
if (!liveConversationState) {
1333-
return readConversationState;
1334-
}
1335-
if (!readConversationState) {
1332+
if (liveConversationState) {
13361333
return liveConversationState;
13371334
}
1338-
1339-
const liveUpdatedAt = getConversationStateUpdatedAt(liveConversationState);
1340-
const readUpdatedAt = getConversationStateUpdatedAt(readConversationState);
1341-
if (liveUpdatedAt > readUpdatedAt) {
1342-
return liveConversationState;
1343-
}
1344-
if (readUpdatedAt > liveUpdatedAt) {
1345-
return readConversationState;
1346-
}
1347-
1348-
return liveConversationState;
1335+
return readConversationState;
13491336
}, [liveState?.conversationState, readThreadState?.thread]);
13501337

13511338
const pendingRequests = useMemo(() => {

apps/web/test/app.test.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,72 @@ describe("App", () => {
774774
expect(await screen.findByTitle("Waiting for user input")).toBeTruthy();
775775
});
776776

777+
it("prefers live-state requests when read thread is newer but has no pending requests", async () => {
778+
const threadId = "thread-live-approval-preferred";
779+
const approvalRequest: UnifiedThreadFixture["requests"][number] = {
780+
id: "approval-live-priority-1",
781+
method: "item/commandExecution/requestApproval",
782+
params: {
783+
threadId,
784+
turnId: "turn-1",
785+
itemId: "item-approval-live-priority-1",
786+
reason: "Need approval from live state",
787+
},
788+
};
789+
790+
threadsFixture = {
791+
ok: true,
792+
data: [
793+
{
794+
id: threadId,
795+
provider: "codex",
796+
preview: "thread preview",
797+
createdAt: 1700000000,
798+
updatedAt: 1700000002,
799+
cwd: "/tmp/project",
800+
source: "codex",
801+
},
802+
],
803+
cursors: {
804+
codex: null,
805+
opencode: null,
806+
},
807+
errors: {
808+
codex: null,
809+
opencode: null,
810+
},
811+
};
812+
813+
readThreadResolver = (targetThreadId: string) => ({
814+
ok: true,
815+
thread: buildConversationStateFixture(targetThreadId, "gpt-old-codex", {
816+
updatedAt: 1700000002,
817+
customRequests: [],
818+
}),
819+
});
820+
821+
liveStateResolver = (targetThreadId: string, _provider: ProviderId) => ({
822+
kind: "readLiveState",
823+
threadId: targetThreadId,
824+
ownerClientId: "client-1",
825+
conversationState: buildConversationStateFixture(
826+
targetThreadId,
827+
"gpt-old-codex",
828+
{
829+
updatedAt: 1700000001,
830+
customRequests: [approvalRequest],
831+
},
832+
),
833+
liveStateError: null,
834+
});
835+
836+
render(<App />);
837+
838+
expect(await screen.findByText("Approval Needed")).toBeTruthy();
839+
expect(await screen.findByText("Need approval from live state")).toBeTruthy();
840+
expect(await screen.findByTitle("Waiting for approval")).toBeTruthy();
841+
});
842+
777843
it("keeps a direct thread route selected when it is readable but not in current thread list page", async () => {
778844
const threadId = "thread-direct-route";
779845
window.history.replaceState(null, "", `/threads/${threadId}`);

0 commit comments

Comments
 (0)