Skip to content

Commit 8bb7b3e

Browse files
committed
fix(providers): derive the limit unit from the ceiling it belongs to
The previous commit fixed OpenAI's "48MB" by dividing every ceiling by 10⁶ — which broke the other seven. Only OpenAI's constant is decimal; anthropic, google, together and openrouter are 50 MiB, baseten and vllm 25 MiB, groq and xai 20 MiB. Rendering those as decimal MB overstated each by ~5%, so a 21 MB file on groq was rejected with "(21MB) exceeds the 21MB limit" — a sentence that contradicts itself and sends the user to shrink a file to a size that is still over. Same class of bug as the one being fixed, sign flipped. Both figures now render through one unit taken from the ceiling, so the number a user is told is the number the vendor publishes and the two sizes in a sentence are always comparable. Tested against every ceiling in the registry rather than only the values that happened to round cleanly. Two more from the same audit: A file with a missing or zero declared size was stranded on a files-api provider: hydration bailed on the real byte length while `shouldUseLargeFilePath` saw `0 > threshold` as false, so it got neither base64 nor a handle and failed as "may no longer be accessible" — a size failure wearing an access failure's message. Uploads read the real bytes and enforce the ceiling themselves, so an unknown size now routes to one. The oversized-attachment error blamed the provider for a deployment problem: a files-api provider on a host without cloud storage reported that the provider "has no large-file upload path", which is not true of the provider. `isFunctionToolCall` only proves `function` is present, never that it is well formed, so the trace enricher is defensive again about a hollow payload without giving up the compile-time gate. The 32 test mocks now match production exactly.
1 parent 092ac94 commit 8bb7b3e

38 files changed

Lines changed: 232 additions & 59 deletions

apps/sim/app/api/knowledge/search/route.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ vi.mock('@/lib/tokenization/estimators', () => ({
4545

4646
vi.mock('@/providers/utils', () => ({
4747
isFunctionToolCall: (toolCall: unknown) =>
48-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
48+
typeof toolCall === 'object' &&
49+
toolCall !== null &&
50+
'function' in toolCall &&
51+
(toolCall as { function?: unknown }).function != null,
4952
calculateCost: vi.fn().mockReturnValue({
5053
input: 0.00001042,
5154
output: 0,

apps/sim/app/api/providers/baseten/models/route.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ const {
1818

1919
vi.mock('@/providers/utils', () => ({
2020
isFunctionToolCall: (toolCall: unknown) =>
21-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
21+
typeof toolCall === 'object' &&
22+
toolCall !== null &&
23+
'function' in toolCall &&
24+
(toolCall as { function?: unknown }).function != null,
2225
filterBlacklistedModels: mockFilterBlacklistedModels,
2326
isProviderBlacklisted: mockIsProviderBlacklisted,
2427
}))

apps/sim/app/api/providers/ollama-cloud/models/route.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ const {
2020

2121
vi.mock('@/providers/utils', () => ({
2222
isFunctionToolCall: (toolCall: unknown) =>
23-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
23+
typeof toolCall === 'object' &&
24+
toolCall !== null &&
25+
'function' in toolCall &&
26+
(toolCall as { function?: unknown }).function != null,
2427
filterBlacklistedModels: mockFilterBlacklistedModels,
2528
isProviderBlacklisted: mockIsProviderBlacklisted,
2629
}))

apps/sim/app/api/providers/together/models/route.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ const {
2020

2121
vi.mock('@/providers/utils', () => ({
2222
isFunctionToolCall: (toolCall: unknown) =>
23-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
23+
typeof toolCall === 'object' &&
24+
toolCall !== null &&
25+
'function' in toolCall &&
26+
(toolCall as { function?: unknown }).function != null,
2427
filterBlacklistedModels: mockFilterBlacklistedModels,
2528
isProviderBlacklisted: mockIsProviderBlacklisted,
2629
}))

apps/sim/blocks/utils.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ vi.mock('@/providers/models', () => ({
4646

4747
vi.mock('@/providers/utils', () => ({
4848
isFunctionToolCall: (toolCall: unknown) =>
49-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
49+
typeof toolCall === 'object' &&
50+
toolCall !== null &&
51+
'function' in toolCall &&
52+
(toolCall as { function?: unknown }).function != null,
5053
getProviderFromModel: vi.fn(() => 'openai'),
5154
}))
5255

apps/sim/ee/access-control/utils/permission-check.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ vi.mock('@/lib/permission-groups/types', () => ({
6767

6868
vi.mock('@/providers/utils', () => ({
6969
isFunctionToolCall: (toolCall: unknown) =>
70-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
70+
typeof toolCall === 'object' &&
71+
toolCall !== null &&
72+
'function' in toolCall &&
73+
(toolCall as { function?: unknown }).function != null,
7174
getProviderFromModel: mockGetProviderFromModel,
7275
}))
7376

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ process.env.NEXT_PUBLIC_APP_URL = 'http://localhost:3000'
3131

3232
vi.mock('@/providers/utils', () => ({
3333
isFunctionToolCall: (toolCall: unknown) =>
34-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
34+
typeof toolCall === 'object' &&
35+
toolCall !== null &&
36+
'function' in toolCall &&
37+
(toolCall as { function?: unknown }).function != null,
3538
getProviderFromModel: vi.fn().mockReturnValue('mock-provider'),
3639
transformBlockTool: vi.fn(),
3740
getBaseModelProviders: vi.fn().mockReturnValue({ openai: {}, anthropic: {} }),

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ import { stringifyJSON } from '@/executor/utils/json'
5353
import { resolveVertexCredential } from '@/executor/utils/vertex-credential'
5454
import { executeProviderRequest } from '@/providers'
5555
import {
56-
formatAttachmentBytes,
56+
formatAttachmentSizes,
57+
getProviderFileStrategy,
5758
shouldUseLargeFilePath,
5859
supportsFileAttachments,
5960
} from '@/providers/attachments'
@@ -978,11 +979,18 @@ export class AgentBlockHandler implements BlockHandler {
978979
!(canUseProviderLargeFilePath(providerId) && shouldUseLargeFilePath(file, providerId))
979980
)
980981
if (missingFile) {
981-
const inlineMB = formatAttachmentBytes(inlineMaxBytes)
982+
const { size: sizeMB, limit: inlineMB } = formatAttachmentSizes(
983+
missingFile.size,
984+
inlineMaxBytes
985+
)
982986
const oversized = Number.isFinite(missingFile.size) && missingFile.size > inlineMaxBytes
987+
const reason =
988+
getProviderFileStrategy(providerId) === 'inline'
989+
? `provider "${providerId}" has no large-file upload path`
990+
: 'this deployment has no cloud file storage for the large-file upload path'
983991
throw new Error(
984992
oversized
985-
? `File "${missingFile.name}" (${formatAttachmentBytes(missingFile.size)}MB) exceeds the ${inlineMB}MB inline attachment limit, and provider "${providerId}" has no large-file upload path for it.`
993+
? `File "${missingFile.name}" (${sizeMB}MB) exceeds the ${inlineMB}MB inline attachment limit, and ${reason}.`
986994
: `File "${missingFile.name}" could not be read for provider "${providerId}". The file may no longer be accessible.`
987995
)
988996
}

apps/sim/executor/handlers/pi/keys.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ vi.mock('@/lib/api-key/byok', () => ({
1919
}))
2020
vi.mock('@/providers/utils', () => ({
2121
isFunctionToolCall: (toolCall: unknown) =>
22-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
22+
typeof toolCall === 'object' &&
23+
toolCall !== null &&
24+
'function' in toolCall &&
25+
(toolCall as { function?: unknown }).function != null,
2326
calculateCost: mockCalculateCost,
2427
shouldBillModelUsage: mockShouldBill,
2528
}))

apps/sim/executor/handlers/pi/pi-handler.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ vi.mock('@/providers/pi-providers', () => ({
7878
}))
7979
vi.mock('@/providers/utils', () => ({
8080
isFunctionToolCall: (toolCall: unknown) =>
81-
typeof toolCall === 'object' && toolCall !== null && 'function' in toolCall,
81+
typeof toolCall === 'object' &&
82+
toolCall !== null &&
83+
'function' in toolCall &&
84+
(toolCall as { function?: unknown }).function != null,
8285
getProviderFromModel: mockGetProviderFromModel,
8386
}))
8487
vi.mock('@/blocks/utils', () => ({

0 commit comments

Comments
 (0)