fix(attachments): allow live opencode image sends
This commit is contained in:
parent
b3d5dbca08
commit
2ac71cd00d
1 changed files with 33 additions and 11 deletions
|
|
@ -2763,11 +2763,26 @@ async function handleSendMessage(
|
||||||
: leadName !== null && memberName === leadName;
|
: leadName !== null && memberName === leadName;
|
||||||
const actionMode = payload.actionMode;
|
const actionMode = payload.actionMode;
|
||||||
|
|
||||||
// Attachments only supported for live lead (stdin content blocks)
|
const recipientProviderId = !isLeadRecipient
|
||||||
if (validatedAttachments?.length && (!isLeadRecipient || !isAlive)) {
|
? await provisioning.resolveRuntimeRecipientProviderId(tn, memberName)
|
||||||
throw new Error(
|
: undefined;
|
||||||
'Attachments are only supported when sending to the team lead while the team is online'
|
const isOpenCodeRecipient = recipientProviderId === 'opencode';
|
||||||
);
|
|
||||||
|
// Attachments are routed through explicit provider transports only.
|
||||||
|
// Native Claude/Codex teammates still read inbox files directly, so storing
|
||||||
|
// attachment metadata there would look successful while silently dropping
|
||||||
|
// the image at runtime. Keep those paths fail-closed until they have a
|
||||||
|
// real runtime attachment transport.
|
||||||
|
if (validatedAttachments?.length) {
|
||||||
|
const supportedLiveLead = isLeadRecipient && isAlive;
|
||||||
|
const supportedLiveOpenCodeRecipient = !isLeadRecipient && isOpenCodeRecipient && isAlive;
|
||||||
|
if (!supportedLiveLead && !supportedLiveOpenCodeRecipient) {
|
||||||
|
throw new Error(
|
||||||
|
isOpenCodeRecipient
|
||||||
|
? 'Attachments for OpenCode teammates require the team to be online'
|
||||||
|
: 'Attachments are supported for the online team lead and online OpenCode teammates only'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart routing: lead + alive → stdin direct, else → inbox
|
// Smart routing: lead + alive → stdin direct, else → inbox
|
||||||
|
|
@ -2897,24 +2912,22 @@ async function handleSendMessage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inbox path: offline lead or regular members (no attachment support)
|
// Inbox path: offline lead or regular members.
|
||||||
const baseText = payload.text!.trim();
|
const baseText = payload.text!.trim();
|
||||||
const replyRecipient =
|
const replyRecipient =
|
||||||
typeof payload.from === 'string' && payload.from.trim().length > 0
|
typeof payload.from === 'string' && payload.from.trim().length > 0
|
||||||
? payload.from.trim()
|
? payload.from.trim()
|
||||||
: 'user';
|
: 'user';
|
||||||
const storedFrom = replyRecipient.toLowerCase() === 'user' ? 'user' : replyRecipient;
|
const storedFrom = replyRecipient.toLowerCase() === 'user' ? 'user' : replyRecipient;
|
||||||
const recipientProviderId = !isLeadRecipient
|
|
||||||
? await provisioning.resolveRuntimeRecipientProviderId(tn, memberName)
|
|
||||||
: undefined;
|
|
||||||
const isOpenCodeRecipient = recipientProviderId === 'opencode';
|
|
||||||
const directReplyProtocol = resolveVisibleDirectReplyProtocol({
|
const directReplyProtocol = resolveVisibleDirectReplyProtocol({
|
||||||
isLeadRecipient,
|
isLeadRecipient,
|
||||||
replyRecipient,
|
replyRecipient,
|
||||||
...(recipientProviderId ? { providerId: recipientProviderId } : {}),
|
...(recipientProviderId ? { providerId: recipientProviderId } : {}),
|
||||||
});
|
});
|
||||||
const inboxMessageId =
|
const inboxMessageId =
|
||||||
directReplyProtocol === 'agent_teams_message_send' ? crypto.randomUUID() : undefined;
|
directReplyProtocol === 'agent_teams_message_send' || validatedAttachments?.length
|
||||||
|
? crypto.randomUUID()
|
||||||
|
: undefined;
|
||||||
const memberDeliveryText = buildMessageDeliveryText(baseText, {
|
const memberDeliveryText = buildMessageDeliveryText(baseText, {
|
||||||
actionMode,
|
actionMode,
|
||||||
isLeadRecipient,
|
isLeadRecipient,
|
||||||
|
|
@ -2925,6 +2938,14 @@ async function handleSendMessage(
|
||||||
...(inboxMessageId ? { messageId: inboxMessageId } : {}),
|
...(inboxMessageId ? { messageId: inboxMessageId } : {}),
|
||||||
});
|
});
|
||||||
const inboxText = isOpenCodeRecipient ? baseText : memberDeliveryText;
|
const inboxText = isOpenCodeRecipient ? baseText : memberDeliveryText;
|
||||||
|
if (validatedAttachments?.length && inboxMessageId) {
|
||||||
|
try {
|
||||||
|
await attachmentStore.saveAttachments(tn, inboxMessageId, validatedAttachments);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Failed to save message attachments: ${getErrorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const result = await getTeamDataService().sendMessage(tn, {
|
const result = await getTeamDataService().sendMessage(tn, {
|
||||||
member: memberName,
|
member: memberName,
|
||||||
text: inboxText,
|
text: inboxText,
|
||||||
|
|
@ -2934,6 +2955,7 @@ async function handleSendMessage(
|
||||||
source: 'user_sent',
|
source: 'user_sent',
|
||||||
taskRefs: validatedTaskRefs.value,
|
taskRefs: validatedTaskRefs.value,
|
||||||
...(inboxMessageId ? { messageId: inboxMessageId } : {}),
|
...(inboxMessageId ? { messageId: inboxMessageId } : {}),
|
||||||
|
...(validatedAttachments?.length ? { attachments: validatedAttachments } : {}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Teammate inbox relay DISABLED (2026-03-23).
|
// Teammate inbox relay DISABLED (2026-03-23).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue