Skip to content

Commit 68b8501

Browse files
committed
fix(cli): preserve local agent wake ordering
1 parent 5350154 commit 68b8501

4 files changed

Lines changed: 676 additions & 9 deletions

File tree

packages/junior/src/chat/local/conversation-work.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ export interface LocalConversationWork {
1212
/**
1313
* Run local conversation work in this process and wait for every accepted wake.
1414
*
15-
* Delayed and follow-up wakes remain tracked so CLI shutdown cannot abandon
16-
* child work that was accepted while an earlier wake was running.
15+
* Wakes start on a later event-loop turn so their producer can persist the
16+
* accepted marker first. Idempotent, delayed, and follow-up wakes remain
17+
* tracked so CLI shutdown cannot abandon accepted child work.
1718
*/
1819
export function createLocalConversationWork(
1920
processMessage: (message: ConversationQueueMessage) => Promise<void>,
2021
): LocalConversationWork {
22+
const acceptedWakeIds = new Map<string, string>();
2123
const pending = new Set<Promise<void>>();
2224
let firstError: unknown;
25+
let nextWakeId = 1;
2326

2427
function schedule(
2528
message: ConversationQueueMessage,
@@ -28,11 +31,9 @@ export function createLocalConversationWork(
2831
const delayMs = Math.max(0, options?.delayMs ?? 0);
2932
let work: Promise<void>;
3033
work = (async () => {
31-
if (delayMs > 0) {
32-
await new Promise<void>((resolve) => {
33-
setTimeout(resolve, delayMs);
34-
});
35-
}
34+
await new Promise<void>((resolve) => {
35+
setTimeout(resolve, delayMs);
36+
});
3637
await processMessage(message);
3738
})()
3839
.catch((error: unknown) => {
@@ -47,7 +48,20 @@ export function createLocalConversationWork(
4748
return {
4849
queue: {
4950
async send(message, options) {
51+
const idempotencyKey = options?.idempotencyKey;
52+
const acceptedWakeId = idempotencyKey
53+
? acceptedWakeIds.get(idempotencyKey)
54+
: undefined;
55+
if (acceptedWakeId) {
56+
return { messageId: acceptedWakeId };
57+
}
58+
const messageId = `local-conversation-work:${nextWakeId}`;
59+
nextWakeId += 1;
60+
if (idempotencyKey) {
61+
acceptedWakeIds.set(idempotencyKey, messageId);
62+
}
5063
schedule(message, options);
64+
return { messageId };
5165
},
5266
},
5367
async drain() {

0 commit comments

Comments
 (0)