fix: skip non-targeted directives when no source adapter context

When sendToAgent() has no valid sourceChannel (e.g. webhook/feed
triggers), filter directives to only those that carry explicit
channel/chat targets. Prevents non-targeted directives (react, voice,
untargeted send-file) from executing against an arbitrary first-registered
adapter.

Written by Cameron ◯ Letta Code

"Simplicity is prerequisite for reliability." -- Edsger Dijkstra
This commit is contained in:
Cameron
2026-03-09 13:10:40 -07:00
parent 542ec8ce45
commit cf47522bf6

View File

@@ -1922,12 +1922,27 @@ export class LettaBot implements AgentSession {
if (response.trim()) {
const parsed = parseDirectives(response);
if (parsed.directives.length > 0) {
const sourceAdapter = (context?.sourceChannel ? this.channels.get(context.sourceChannel) : undefined)
?? this.channels.values().next().value;
if (sourceAdapter) {
executedDirectives = await this.executeDirectives(
parsed.directives, sourceAdapter, context?.sourceChatId ?? '',
const sourceAdapter = context?.sourceChannel ? this.channels.get(context.sourceChannel) : undefined;
const sourceChatId = context?.sourceChatId ?? '';
// Without a valid source adapter, only explicitly targeted directives can run.
// Non-targeted directives (react, voice, untargeted send-file) need a source
// chat context and must be filtered out to avoid executing against a wrong channel.
const directives = sourceAdapter
? parsed.directives
: parsed.directives.filter(d =>
d.type === 'send-message' || (d.type === 'send-file' && d.channel && d.chat)
);
if (directives.length > 0) {
// Targeted directives resolve their own adapter; the fallback here is only
// used by non-targeted directives (which are filtered out when no source).
const adapter = sourceAdapter ?? this.channels.values().next().value;
if (adapter) {
executedDirectives = await this.executeDirectives(
directives, adapter, sourceChatId,
);
}
}
response = parsed.cleanText;
}