Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/code/snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ snapshots:
archive-archivedtasksview--many-tasks--dark:
hash: v1.k4693efd2.40d24f07a24c6400c32ae68b39fd908a056beb5dc6df8bcb237ec2ab2b494f4a.l2vjfSQDalCPRtDNV7pbfTKGlMsQoI81jI-UdJfLHWE
archive-archivedtasksview--many-tasks--light:
hash: v1.k4693efd2.52ec9963bfe6f248ffcdaa4c26945d2b7e303115825b65d978aa5aefd4af1007.ZLtOfTZUrznhYeB-N2SIHzQWRzF6TDSaipNkfd8uzjM
hash: v1.k4693efd2.74c25b303262f2d4c0f22890d351e76f482827548548f7c023bc309327c927b8.DP9VVrvBz1naIJMwHORkfqm69BlO785ulOt4o6zFs94
archive-archivedtasksview--mixed-modes--dark:
hash: v1.k4693efd2.d94039b8cc17a4ad1b720364f41fee58a4843aa9a901443997ba62602f698794.441LWZhT-2WQZJHni4LoOgQsOSr2O103NZOk1pF8ME4
archive-archivedtasksview--mixed-modes--light:
Expand Down
19 changes: 15 additions & 4 deletions packages/core/src/sessions/cloudTaskUpdateNotifications.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,14 @@ describe("cloud task update notifications", () => {
});

// Each case applies a sequence of updates to a fresh harness; `expected` is
// the resulting notify count. Snapshots never ring; each live turn_complete
// rings once. Re-delivered stream entries are dropped upstream in
// CloudTaskService by their event id (see cloud-task.test.ts), so a replay
// never reaches this layer.
// the resulting notify count. Snapshots never ring; each armed turn rings at
// most once even if the producer writes duplicate completion entries.
it.each([
{
label: "a completion event without an armed turn",
updates: [logsUpdate([turnComplete()], 1)],
expected: 0,
},
{
label: "a live turn that starts and completes",
updates: [logsUpdate([sessionPrompt(1), turnComplete()], 2)],
Expand All @@ -224,6 +227,14 @@ describe("cloud task update notifications", () => {
],
expected: 2,
},
{
label: "duplicate completion events for one turn",
updates: [
logsUpdate([sessionPrompt(1), turnComplete()], 2),
logsUpdate([turnComplete()], 3),
],
expected: 1,
},
{
// Opening a task mid-turn: its session/prompt is already in history and
// only the turn_complete arrives live. The completion must still ring.
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/sessions/sessionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,9 @@ export class SessionService {
// above. Cloud sessions never see that response.
const session = this.getSessionByRunId(taskRunId);
if (session?.isCloud) {
const completedActiveTurn =
session.currentPromptId !== null &&
session.currentPromptId !== undefined;
const turnStartedAtTs =
this.liveTurnContent.get(taskRunId)?.startedAtTs ??
session.promptStartedAt;
Expand All @@ -1957,7 +1960,7 @@ export class SessionService {
});
if (isLive) {
// Queued messages will start a new turn — suppress the "done" notification in that case.
if (session.messageQueue.length === 0) {
if (completedActiveTurn && session.messageQueue.length === 0) {
this.d.notifyPromptComplete(
session.taskTitle,
"end_turn",
Expand Down
Loading