Skip to content

Commit f1889ad

Browse files
committed
fix(providers): stop an over-limit size rendering as the limit itself
Deriving the unit from the ceiling fixed the 5% error but left the precision fixed at two decimals, so a file one byte over a 20 MiB cap still printed "(20.00MB) exceeds the 20MB agent attachment limit" — the same self-contradicting sentence, now in a ~5 KB band above every ceiling in the registry. The size rounds up and the ceiling rounds down, so the two can no longer collide. The test that was supposed to guard this asserted a file 0.03MB over and an OpenAI file that was under the limit — neither anywhere near the band — so it passed while the bug was live. It now walks `limit + 1` for every ceiling, and goes red against the old rounding. The reason clause added last commit also claimed a deployment had no cloud file storage whenever the strategy was not inline. A generated document on a remote-url provider reaches that same error with storage fully configured, because a signed URL points at the generation source rather than the rendered artifact — so it was told something false about its own deployment. That case now names itself.
1 parent 8bb7b3e commit f1889ad

3 files changed

Lines changed: 34 additions & 10 deletions

File tree

apps/sim/executor/handlers/agent/agent-handler.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
SIM_AUTO_SYSTEM_PREAMBLE,
1616
} from '@/lib/model-router/resolve'
1717
import {
18+
isGeneratedDocumentSourceType,
1819
MODEL_SUPPORTED_IMAGE_MIME_TYPES,
1920
processFilesToUserFiles,
2021
type RawFileInput,
@@ -984,8 +985,9 @@ export class AgentBlockHandler implements BlockHandler {
984985
inlineMaxBytes
985986
)
986987
const oversized = Number.isFinite(missingFile.size) && missingFile.size > inlineMaxBytes
987-
const reason =
988-
getProviderFileStrategy(providerId) === 'inline'
988+
const reason = isGeneratedDocumentSourceType(missingFile.type)
989+
? `a generated document cannot use the large-file path for provider "${providerId}"`
990+
: getProviderFileStrategy(providerId) === 'inline'
989991
? `provider "${providerId}" has no large-file upload path`
990992
: 'this deployment has no cloud file storage for the large-file upload path'
991993
throw new Error(

apps/sim/providers/attachments.test.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,31 @@ describe('attachment limit formatting', () => {
302302
expect(formatAttachmentSizes(0, 10 * 1024 * 1024).limit).toBe('10')
303303
})
304304

305-
/** The size and the ceiling share a unit, so the sentence can never contradict itself. */
305+
/**
306+
* Exercises `limit + 1` for every ceiling in the registry, which is the only input that can
307+
* expose this: rounding both figures to the nearest hundredth rendered a file one byte over a
308+
* 20 MiB cap as "20.00MB exceeds the 20MB limit". The previous version of this test asserted
309+
* a file 0.03MB over and an openai file *under* the limit, so it passed while that was live.
310+
*/
306311
it('never renders an over-limit file as equal to the limit', () => {
312+
const ceilings = [
313+
50 * 1024 * 1024,
314+
25 * 1024 * 1024,
315+
20 * 1024 * 1024,
316+
10 * 1024 * 1024,
317+
6 * 1024 * 1024,
318+
50_000_000,
319+
]
320+
for (const limit of ceilings) {
321+
const justOver = formatAttachmentSizes(limit + 1, limit)
322+
expect(justOver.size).not.toBe(justOver.limit)
323+
}
324+
})
325+
326+
it('keeps a comfortably over-limit size readable', () => {
307327
const groq = formatAttachmentSizes(21_000_000, 20 * 1024 * 1024)
308328
expect(groq.limit).toBe('20')
309329
expect(groq.size).toBe('20.03')
310-
311-
const openai = formatAttachmentSizes(9_591_617, 50_000_000)
312-
expect(openai.limit).toBe('50')
313-
expect(openai.size).toBe('9.59')
314330
})
315331
})
316332

apps/sim/providers/attachments.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,17 @@ export function formatAttachmentSizes(
237237
limitBytes: number
238238
): { size: string; limit: string } {
239239
const divisor = limitBytes % MEBIBYTE === 0 ? MEBIBYTE : 1_000_000
240-
const render = (value: number) => {
241-
const scaled = value / divisor
240+
/**
241+
* The size rounds up and the ceiling rounds down, so an over-limit file can never render as
242+
* the same number as the limit it broke. Rounding both to the nearest hundredth instead let a
243+
* file one byte over a 20 MiB cap print as "20.00MB exceeds the 20MB limit" — a sentence that
244+
* tells the user to shrink to a size they are already under.
245+
*/
246+
const render = (value: number, round: (n: number) => number) => {
247+
const scaled = round((value / divisor) * 100) / 100
242248
return Number.isInteger(scaled) ? String(scaled) : scaled.toFixed(2)
243249
}
244-
return { size: render(bytes), limit: render(limitBytes) }
250+
return { size: render(bytes, Math.ceil), limit: render(limitBytes, Math.floor) }
245251
}
246252

247253
export function inferAttachmentMimeType(file: UserFile): string {

0 commit comments

Comments
 (0)