(
filename: string,
toolUseContext: ToolUseContext,
successEventName: string,
errorEventName: string,
mode: 'compact' | 'at-mention',
options?: {
offset?: number
limit?: number
},
)
| 3100 | } |
| 3101 | |
| 3102 | export async function generateFileAttachment( |
| 3103 | filename: string, |
| 3104 | toolUseContext: ToolUseContext, |
| 3105 | successEventName: string, |
| 3106 | errorEventName: string, |
| 3107 | mode: 'compact' | 'at-mention', |
| 3108 | options?: { |
| 3109 | offset?: number |
| 3110 | limit?: number |
| 3111 | }, |
| 3112 | ): Promise< |
| 3113 | | FileAttachment |
| 3114 | | CompactFileReferenceAttachment |
| 3115 | | PDFReferenceAttachment |
| 3116 | | AlreadyReadFileAttachment |
| 3117 | | null |
| 3118 | > { |
| 3119 | const { offset, limit } = options ?? {} |
| 3120 | |
| 3121 | // Check if file has a deny rule configured |
| 3122 | const appState = toolUseContext.getAppState() |
| 3123 | if (isFileReadDenied(filename, appState.toolPermissionContext)) { |
| 3124 | return null |
| 3125 | } |
| 3126 | |
| 3127 | // Check file size before attempting to read (skip for PDFs — they have their own size/page handling below) |
| 3128 | if ( |
| 3129 | mode === 'at-mention' && |
| 3130 | !isFileWithinReadSizeLimit( |
| 3131 | filename, |
| 3132 | getDefaultFileReadingLimits().maxSizeBytes, |
| 3133 | ) |
| 3134 | ) { |
| 3135 | const ext = parse(filename).ext.toLowerCase() |
| 3136 | if (!isPDFExtension(ext)) { |
| 3137 | try { |
| 3138 | const stats = await getFsImplementation().stat(filename) |
| 3139 | logEvent('tengu_attachment_file_too_large', { |
| 3140 | size_bytes: stats.size, |
| 3141 | mode, |
| 3142 | } as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS) |
| 3143 | return null |
| 3144 | } catch { |
| 3145 | // If we can't stat the file, proceed with normal reading (will fail later if file doesn't exist) |
| 3146 | } |
| 3147 | } |
| 3148 | } |
| 3149 | |
| 3150 | // For large PDFs on @ mention, return a lightweight reference instead of inlining |
| 3151 | if (mode === 'at-mention') { |
| 3152 | const pdfRef = await tryGetPDFReference(filename) |
| 3153 | if (pdfRef) { |
| 3154 | return pdfRef |
| 3155 | } |
| 3156 | } |
| 3157 | |
| 3158 | // Check if file is already in context with latest version |
| 3159 | const existingFileState = toolUseContext.readFileState.get(filename) |
no test coverage detected