Skip to content

Commit 6dba7cc

Browse files
[verified] fix(server): harden bounded shell summaries
Co-authored-by: maria <[email protected]>
1 parent cb3e6e6 commit 6dba7cc

8 files changed

Lines changed: 1132 additions & 191 deletions

‎apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts‎

Lines changed: 342 additions & 11 deletions
Large diffs are not rendered by default.

‎apps/server/src/orchestration/Layers/ProjectionPipeline.ts‎

Lines changed: 17 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -130,60 +130,6 @@ function isStalePendingApprovalFailureDetail(detail: string | null): boolean {
130130
);
131131
}
132132

133-
function isStalePendingUserInputFailureDetail(detail: string | null): boolean {
134-
if (detail === null) {
135-
return false;
136-
}
137-
return (
138-
detail.includes("stale pending user-input request") ||
139-
detail.includes("unknown pending user-input request") ||
140-
detail.includes("unknown pending user input request") ||
141-
detail.includes("unknown pending codex user input request")
142-
);
143-
}
144-
145-
function derivePendingUserInputCountFromActivities(
146-
activities: ReadonlyArray<ProjectionThreadActivity>,
147-
): number {
148-
const openRequestIds = new Set<string>();
149-
const ordered = [...activities].toSorted(
150-
(left, right) =>
151-
left.createdAt.localeCompare(right.createdAt) ||
152-
left.activityId.localeCompare(right.activityId),
153-
);
154-
155-
for (const activity of ordered) {
156-
const requestId = extractActivityRequestId(activity.payload);
157-
if (requestId === null) {
158-
continue;
159-
}
160-
const payload =
161-
typeof activity.payload === "object" && activity.payload !== null
162-
? (activity.payload as Record<string, unknown>)
163-
: null;
164-
const detail = typeof payload?.detail === "string" ? payload.detail.toLowerCase() : null;
165-
166-
if (activity.kind === "user-input.requested") {
167-
openRequestIds.add(requestId);
168-
continue;
169-
}
170-
171-
if (activity.kind === "user-input.resolved") {
172-
openRequestIds.delete(requestId);
173-
continue;
174-
}
175-
176-
if (
177-
activity.kind === "provider.user-input.respond.failed" &&
178-
isStalePendingUserInputFailureDetail(detail)
179-
) {
180-
openRequestIds.delete(requestId);
181-
}
182-
}
183-
184-
return openRequestIds.size;
185-
}
186-
187133
function deriveHasActionableProposedPlan(input: {
188134
readonly latestTurnId: string | null;
189135
readonly proposedPlans: ReadonlyArray<ProjectionThreadProposedPlan>;
@@ -570,27 +516,18 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
570516
return;
571517
}
572518

573-
const [messages, proposedPlans, activities, pendingApprovals] = yield* Effect.all([
574-
projectionThreadMessageRepository.listByThreadId({ threadId }),
575-
projectionThreadProposedPlanRepository.listByThreadId({ threadId }),
576-
projectionThreadActivityRepository.listByThreadId({ threadId }),
577-
projectionPendingApprovalRepository.listByThreadId({ threadId }),
578-
]);
579-
580-
let latestUserMessageAt: string | null = null;
581-
for (const message of messages) {
582-
if (
583-
message.role === "user" &&
584-
(latestUserMessageAt === null || message.createdAt > latestUserMessageAt)
585-
) {
586-
latestUserMessageAt = message.createdAt;
587-
}
588-
}
519+
const [latestUserMessageAtOption, proposedPlans, pendingUserInputCount, pendingApprovals] =
520+
yield* Effect.all([
521+
projectionThreadMessageRepository.getLatestUserMessageAtByThreadId({ threadId }),
522+
projectionThreadProposedPlanRepository.listByThreadId({ threadId }),
523+
projectionThreadActivityRepository.countPendingUserInputsByThreadId({ threadId }),
524+
projectionPendingApprovalRepository.listByThreadId({ threadId }),
525+
]);
589526

527+
const latestUserMessageAt = Option.getOrNull(latestUserMessageAtOption);
590528
const pendingApprovalCount = pendingApprovals.filter(
591529
(approval) => approval.status === "pending",
592530
).length;
593-
const pendingUserInputCount = derivePendingUserInputCountFromActivities(activities);
594531
const hasActionableProposedPlan = deriveHasActionableProposedPlan({
595532
latestTurnId: existingRow.value.latestTurnId,
596533
proposedPlans,
@@ -877,20 +814,11 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
877814

878815
switch (event.type) {
879816
case "thread.message-sent": {
880-
if (event.payload.role !== "user") {
881-
break;
882-
}
883-
const projectedMessage = yield* projectionThreadMessageRepository.getByMessageId({
884-
messageId: event.payload.messageId,
885-
});
886-
if (
887-
Option.isSome(projectedMessage) &&
888-
projectedMessage.value.role === "user" &&
889-
(latestUserMessageAt === null ||
890-
projectedMessage.value.createdAt > latestUserMessageAt)
891-
) {
892-
latestUserMessageAt = projectedMessage.value.createdAt;
893-
}
817+
latestUserMessageAt = Option.getOrNull(
818+
yield* projectionThreadMessageRepository.getLatestUserMessageAtByThreadId({
819+
threadId: event.payload.threadId,
820+
}),
821+
);
894822
break;
895823
}
896824

@@ -931,17 +859,10 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
931859
).length;
932860
}
933861

934-
if (
935-
kind === "user-input.requested" ||
936-
kind === "user-input.resolved" ||
937-
(kind === "provider.user-input.respond.failed" &&
938-
isStalePendingUserInputFailureDetail(detail))
939-
) {
940-
pendingUserInputCount =
941-
yield* projectionThreadActivityRepository.countPendingUserInputsByThreadId({
942-
threadId: event.payload.threadId,
943-
});
944-
}
862+
pendingUserInputCount =
863+
yield* projectionThreadActivityRepository.countPendingUserInputsByThreadId({
864+
threadId: event.payload.threadId,
865+
});
945866
break;
946867
}
947868

0 commit comments

Comments
 (0)