diff --git a/src/task-scheduler.test.ts b/src/task-scheduler.test.ts index 56b7cf4..73f3a2a 100644 --- a/src/task-scheduler.test.ts +++ b/src/task-scheduler.test.ts @@ -106,9 +106,52 @@ describe('task scheduler', () => { await vi.advanceTimersByTimeAsync(10); expect(enqueueTask).toHaveBeenCalledTimes(1); + expect(enqueueTask.mock.calls[0][0]).toBe('shared@g.us::task:task-codex'); expect(enqueueTask.mock.calls[0][1]).toBe('task-codex'); }); + it('keeps group-context tasks on the chat queue key', async () => { + const dueAt = new Date(Date.now() - 60_000).toISOString(); + createTask({ + id: 'task-group-context', + group_folder: 'shared-group', + chat_jid: 'shared@g.us', + agent_type: 'codex', + prompt: 'group context task', + schedule_type: 'once', + schedule_value: dueAt, + context_mode: 'group', + next_run: dueAt, + status: 'active', + created_at: '2026-02-22T00:00:00.000Z', + }); + + const enqueueTask = vi.fn(); + + startSchedulerLoop({ + serviceAgentType: 'codex', + registeredGroups: () => ({ + 'shared@g.us': { + name: 'Shared', + folder: 'shared-group', + trigger: '@Codex', + added_at: '2026-02-22T00:00:00.000Z', + agentType: 'codex', + }, + }), + getSessions: () => ({}), + queue: { enqueueTask } as any, + onProcess: () => {}, + sendMessage: async () => {}, + }); + + await vi.advanceTimersByTimeAsync(10); + + expect(enqueueTask).toHaveBeenCalledTimes(1); + expect(enqueueTask.mock.calls[0][0]).toBe('shared@g.us'); + expect(enqueueTask.mock.calls[0][1]).toBe('task-group-context'); + }); + it('renders watcher heartbeat messages with target and timing', () => { const prompt = ` [BACKGROUND CI WATCH] diff --git a/src/task-scheduler.ts b/src/task-scheduler.ts index 9290fc7..ec61444 100644 --- a/src/task-scheduler.ts +++ b/src/task-scheduler.ts @@ -202,6 +202,14 @@ export function renderWatchCiStatusMessage(args: { return lines.join('\n'); } +function getTaskQueueJid( + task: Pick, +): string { + return task.context_mode === 'isolated' + ? `${task.chat_jid}::task:${task.id}` + : task.chat_jid; +} + async function runTask( task: ScheduledTask, deps: SchedulerDependencies, @@ -279,6 +287,7 @@ async function runTask( let error: string | null = null; let statusMessageId = task.status_message_id; let statusStartedAt = task.status_started_at; + const queueJid = getTaskQueueJid(task); // For group context mode, use the group's current session const sessions = deps.getSessions(); @@ -354,7 +363,7 @@ async function runTask( assistantName: ASSISTANT_NAME, }, (proc, processName) => - deps.onProcess(task.chat_jid, proc, processName, task.group_folder), + deps.onProcess(queueJid, proc, processName, task.group_folder), async (streamedOutput: AgentOutput) => { if (streamedOutput.phase === 'progress') { return; @@ -452,7 +461,7 @@ export function startSchedulerLoop(deps: SchedulerDependencies): void { continue; } - deps.queue.enqueueTask(currentTask.chat_jid, currentTask.id, () => + deps.queue.enqueueTask(getTaskQueueJid(currentTask), currentTask.id, () => runTask(currentTask, deps), ); }