Skip to content

Commit fdcd21b

Browse files
armanossilokoclaude
andcommitted
fix(queue): another device can't send a queued message that is being edited
Send now only knew about edits on the same device, so another device could start or steer a held message with its original text. The server now rejects both for a message being edited, with an error saying why. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent 8771f41 commit fdcd21b

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

‎apps/server/src/orchestration-v2/Orchestrator.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,9 @@ function worktreeSetupPending(
758758
);
759759
}
760760

761+
const QUEUED_RUN_BEING_EDITED =
762+
"This queued message is being edited. Save or cancel the edit first.";
763+
761764
function nextQueuedRun(
762765
projection: Pick<OrchestrationV2ThreadProjection, "runs" | "messages">,
763766
): OrchestrationV2Run | undefined {
@@ -9279,6 +9282,13 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio
92799282
cause: `Queued run ${command.queuedRunId} is not queued.`,
92809283
});
92819284
}
9285+
if (queuedRun.editing === true) {
9286+
return yield* new OrchestratorDispatchError({
9287+
commandId: command.commandId,
9288+
commandType: command.type,
9289+
cause: QUEUED_RUN_BEING_EDITED,
9290+
});
9291+
}
92829292
const queuedRootNode =
92839293
queuedRun.rootNodeId === null
92849294
? undefined
@@ -13156,6 +13166,13 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio
1315613166
cause: "A queued user message can only be sent now while the thread is stopped.",
1315713167
});
1315813168
}
13169+
if (selectedRun.editing === true) {
13170+
return yield* new OrchestratorDispatchError({
13171+
commandId: command.commandId,
13172+
commandType: command.type,
13173+
cause: QUEUED_RUN_BEING_EDITED,
13174+
});
13175+
}
1315913176
}
1316013177
const nextRun = selectedRun ?? queuedRunsInDeliveryOrder(projection)[0];
1316113178
if (

‎apps/server/src/orchestration-v2/runtimeLayer.test.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5829,7 +5829,16 @@ it.layer(layerTest)("OrchestrationV2LayerLive lifecycle", (it) => {
58295829
["completed", "queued", "queued"],
58305830
);
58315831

5832-
// Sending another message now keeps the edit hold.
5832+
// Another device cannot send the edited message, but can send the others.
5833+
const rejected = yield* orchestrator
5834+
.dispatch({
5835+
type: "queued-run.start",
5836+
commandId: CommandId.make(`${threadId}:send-edited`),
5837+
threadId,
5838+
runId: edited!.id,
5839+
})
5840+
.pipe(Effect.flip);
5841+
assert.equal(rejected._tag, "OrchestratorDispatchError");
58335842
yield* orchestrator.dispatch({
58345843
type: "queued-run.start",
58355844
commandId: CommandId.make(`${threadId}:send-behind`),

0 commit comments

Comments
 (0)