// Common audio file extensions for transcription detection const AUDIO_EXTENSIONS = new Set([ ".ogg", ".opus", ".mp3", ".m4a", ".wav", ".webm", ".flac", ".aac", ".wma", ".aiff", ".alac", ".oga",
]);
function isAudioPath(path: string | undefined): boolean { if (!path) { returnfalse;
} const lower = normalizeLowercaseStringOrEmpty(path); for (const ext of AUDIO_EXTENSIONS) { if (lower.endsWith(ext)) { returntrue;
}
} returnfalse;
}
function isValidAttachmentIndex(index: number, attachmentCount: number): boolean { return Number.isSafeInteger(index) && index >= 0 && index < attachmentCount;
}
function collectTranscribedAudioAttachmentIndices(
ctx: MsgContext,
attachmentCount: number,
): Set<number> { // Only audio transcription should suppress the raw attachment in prompt notes. // Image/video descriptions are lossy derived context, so the original attachment // must stay available to multimodal models and downstream tools. const transcribedAudioIndices = new Set<number>(); if (Array.isArray(ctx.MediaUnderstanding)) { for (const output of ctx.MediaUnderstanding) { if (
output.kind === "audio.transcription" &&
isValidAttachmentIndex(output.attachmentIndex, attachmentCount)
) {
transcribedAudioIndices.add(output.attachmentIndex);
}
}
} if (Array.isArray(ctx.MediaUnderstandingDecisions)) { for (const decision of ctx.MediaUnderstandingDecisions) { if (decision.capability !== "audio" || decision.outcome !== "success") { continue;
} for (const attachment of decision.attachments) { if (
attachment.chosen?.outcome === "success" &&
isValidAttachmentIndex(attachment.attachmentIndex, attachmentCount)
) {
transcribedAudioIndices.add(attachment.attachmentIndex);
}
}
}
} return transcribedAudioIndices;
}
export function buildInboundMediaNote(ctx: MsgContext): string | undefined { // Attachment indices follow MediaPaths/MediaUrls ordering as supplied by the channel. const pathsFromArray = Array.isArray(ctx.MediaPaths) ? ctx.MediaPaths : undefined; const paths =
pathsFromArray && pathsFromArray.length > 0
? pathsFromArray
: ctx.MediaPath?.trim()
? [ctx.MediaPath.trim()]
: []; if (paths.length === 0) { return undefined;
}
const urls =
Array.isArray(ctx.MediaUrls) && ctx.MediaUrls.length === paths.length
? ctx.MediaUrls
: undefined; const types =
Array.isArray(ctx.MediaTypes) && ctx.MediaTypes.length === paths.length
? ctx.MediaTypes
: undefined; const hasTranscript = Boolean(ctx.Transcript?.trim()); // Transcript alone does not identify an attachment index; only use it as a fallback // when there is a single attachment to avoid stripping unrelated audio files. const canStripSingleAttachmentByTranscript = hasTranscript && paths.length === 1;
const entries = paths
.map((entry, index) => ({
path: entry ?? "",
type: types?.[index] ?? ctx.MediaType,
url: urls?.[index] ?? ctx.MediaUrl,
index,
}))
.filter((entry) => { // Strip audio attachments when transcription succeeded - the transcript is already // available in the context, raw audio binary would only waste tokens (issue #4197) // Note: Only trust MIME type from per-entry types array, not fallback ctx.MediaType // which could misclassify non-audio attachments (greptile review feedback) const hasPerEntryType = types !== undefined; const isAudioByMime =
hasPerEntryType && normalizeLowercaseStringOrEmpty(entry.type).startsWith("audio/"); const isAudioEntry = isAudioPath(entry.path) || isAudioByMime; if (!isAudioEntry) { returntrue;
} if (
transcribedAudioIndices.has(entry.index) ||
(canStripSingleAttachmentByTranscript && entry.index === 0)
) { returnfalse;
} returntrue;
}); if (entries.length === 0) { return undefined;
} if (entries.length === 1) { return formatMediaAttachedLine({
path: entries[0]?.path ?? "",
type: entries[0]?.type,
url: entries[0]?.url,
});
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.