address review: add thread resolution test, log catch, remove stray comment
- Add integration test for per-destination thread_id resolution: seeds two destinations with different thread IDs, verifies each outbound message carries the correct thread_id (not a global one from the batch routing). - Add log line in resolveDestinationThread catch block for debuggability. - Remove stray "(ensurePreCompactHook is defined after the main function.)" comment from group-init.ts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,44 @@ describe('poll loop integration', () => {
|
|||||||
await loopPromise.catch(() => {});
|
await loopPromise.catch(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should resolve thread_id per-destination, not from global routing', async () => {
|
||||||
|
// Seed a second destination
|
||||||
|
getInboundDb()
|
||||||
|
.prepare(
|
||||||
|
`INSERT INTO destinations (name, display_name, type, channel_type, platform_id, agent_group_id)
|
||||||
|
VALUES ('slack-test', 'Slack Test', 'channel', 'slack', 'chan-2', NULL)`,
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
// Insert messages from each destination with distinct thread IDs
|
||||||
|
insertMessage('m-discord', { sender: 'Alice', text: 'from discord' }, { platformId: 'chan-1', channelType: 'discord', threadId: 'discord-thread-1' });
|
||||||
|
insertMessage('m-slack', { sender: 'Bob', text: 'from slack' }, { platformId: 'chan-2', channelType: 'slack', threadId: 'slack-thread-99' });
|
||||||
|
|
||||||
|
// Agent replies to both destinations
|
||||||
|
const provider = new MockProvider({}, () =>
|
||||||
|
'<message to="discord-test">reply-d</message><message to="slack-test">reply-s</message>',
|
||||||
|
);
|
||||||
|
const controller = new AbortController();
|
||||||
|
const loopPromise = runPollLoopWithTimeout(provider, controller.signal, 2000);
|
||||||
|
|
||||||
|
await waitFor(() => getUndeliveredMessages().length >= 2, 2000);
|
||||||
|
controller.abort();
|
||||||
|
|
||||||
|
const out = getUndeliveredMessages();
|
||||||
|
const discordOut = out.find((m) => m.platform_id === 'chan-1');
|
||||||
|
const slackOut = out.find((m) => m.platform_id === 'chan-2');
|
||||||
|
|
||||||
|
expect(discordOut).toBeDefined();
|
||||||
|
expect(discordOut!.thread_id).toBe('discord-thread-1');
|
||||||
|
expect(discordOut!.in_reply_to).toBe('m-discord');
|
||||||
|
|
||||||
|
expect(slackOut).toBeDefined();
|
||||||
|
expect(slackOut!.thread_id).toBe('slack-thread-99');
|
||||||
|
expect(slackOut!.in_reply_to).toBe('m-slack');
|
||||||
|
|
||||||
|
await loopPromise.catch(() => {});
|
||||||
|
});
|
||||||
|
|
||||||
it('should process messages arriving after loop starts', async () => {
|
it('should process messages arriving after loop starts', async () => {
|
||||||
const provider = new MockProvider({}, () => '<message to="discord-test">Processed</message>');
|
const provider = new MockProvider({}, () => '<message to="discord-test">Processed</message>');
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
|
|||||||
@@ -478,8 +478,8 @@ function resolveDestinationThread(
|
|||||||
)
|
)
|
||||||
.get(channelType, platformId) as { thread_id: string | null; id: string } | undefined;
|
.get(channelType, platformId) as { thread_id: string | null; id: string } | undefined;
|
||||||
if (row) return { threadId: row.thread_id, inReplyTo: row.id };
|
if (row) return { threadId: row.thread_id, inReplyTo: row.id };
|
||||||
} catch {
|
} catch (err) {
|
||||||
// Fall through — DB may not have these columns on older sessions
|
log(`resolveDestinationThread error: ${err instanceof Error ? err.message : String(err)}`);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ export function initGroupFilesystem(group: AgentGroup, opts?: { instructions?: s
|
|||||||
|
|
||||||
// Skills directory — created empty here; symlinks are synced at spawn
|
// Skills directory — created empty here; symlinks are synced at spawn
|
||||||
// time by container-runner.ts based on container.json skills selection.
|
// time by container-runner.ts based on container.json skills selection.
|
||||||
// (ensurePreCompactHook is defined after the main function.)
|
|
||||||
const skillsDst = path.join(claudeDir, 'skills');
|
const skillsDst = path.join(claudeDir, 'skills');
|
||||||
if (!fs.existsSync(skillsDst)) {
|
if (!fs.existsSync(skillsDst)) {
|
||||||
fs.mkdirSync(skillsDst, { recursive: true });
|
fs.mkdirSync(skillsDst, { recursive: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user