fix(web): cap default images at 5 MiB
This commit is contained in:
@@ -12,7 +12,7 @@ export { detectImage } from './image.ts'
|
||||
export { readImageFile, saveImageFile, validateImageFile } from './store.ts'
|
||||
|
||||
/** Default maximum encoded bytes for one image. */
|
||||
export const DEFAULT_MAX_IMAGE_BYTES = 10 * 1024 * 1024
|
||||
export const DEFAULT_MAX_IMAGE_BYTES = 5 * 1024 * 1024
|
||||
/** Default maximum images in one prompt. */
|
||||
export const DEFAULT_MAX_IMAGES_PER_MESSAGE = 20
|
||||
/** Default maximum aggregate image bytes in one prompt. */
|
||||
|
||||
@@ -14,6 +14,7 @@ import LocalAttachmentStore, {
|
||||
describe('local attachment service', () => {
|
||||
it('resolves every omitted admission limit explicitly', () => {
|
||||
const service = new LocalAttachmentStore(new Context(), {})
|
||||
expect(DEFAULT_MAX_IMAGE_BYTES).toBe(5 * 1024 * 1024)
|
||||
expect(service.imageLimits).toEqual({
|
||||
maxImageBytes: DEFAULT_MAX_IMAGE_BYTES,
|
||||
maxImagesPerMessage: DEFAULT_MAX_IMAGES_PER_MESSAGE,
|
||||
|
||||
@@ -985,7 +985,7 @@ function projectionValuesOf(log: readonly SessionEvent[]): Record<string, unknow
|
||||
// change frame (constant unit), but the fixture's uniform baseline replay
|
||||
// frames every key here, incidentally exercising higher-seq-wins.
|
||||
values['imageLimits'] = {
|
||||
maxImageBytes: 10 * 1024 * 1024,
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
|
||||
@@ -165,7 +165,7 @@ describe('createFixtureApi', () => {
|
||||
messageTokens: 0,
|
||||
},
|
||||
imageLimits: {
|
||||
maxImageBytes: 10 * 1024 * 1024,
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
@@ -383,7 +383,7 @@ describe('createFixtureApi', () => {
|
||||
expect((first[8]?.payload as { value: { messageTokens: number } }).value.messageTokens).toBeGreaterThan(0)
|
||||
expect(first[9]?.payload).toMatchObject({
|
||||
type: 'session/projection', sessionId: 'fx-alpha', key: 'imageLimits',
|
||||
value: { maxImagesPerMessage: 20, maxImageBytes: 10 * 1024 * 1024 },
|
||||
value: { maxImagesPerMessage: 20, maxImageBytes: 5 * 1024 * 1024 },
|
||||
})
|
||||
expect(first[10]?.payload).toMatchObject({ type: 'approval/requested', toolName: 'dangerous_tool' })
|
||||
expect(second[10]?.rpcId).toBe(first[10]?.rpcId) // stable rpcId across replays (host replay semantics)
|
||||
|
||||
@@ -9,12 +9,12 @@ afterEach(cleanup)
|
||||
describe('DropOverlay', () => {
|
||||
it('portals the invitation with its title and limits desc to the body', () => {
|
||||
const view = render(
|
||||
<DropOverlay disabled={false} labels={{ title: '图片拖动到此处即可添加', desc: '最多 20 张,每张 10MB' }} />,
|
||||
<DropOverlay disabled={false} labels={{ title: '图片拖动到此处即可添加', desc: '最多 20 张,每张 5MB' }} />,
|
||||
)
|
||||
const overlay = view.getByRole('status')
|
||||
expect(overlay.parentElement).toBe(document.body)
|
||||
expect(overlay.textContent).toContain('图片拖动到此处即可添加')
|
||||
expect(overlay.textContent).toContain('最多 20 张,每张 10MB')
|
||||
expect(overlay.textContent).toContain('最多 20 张,每张 5MB')
|
||||
})
|
||||
|
||||
it('omits the desc line when none is resolved', () => {
|
||||
|
||||
@@ -28,7 +28,7 @@ const attachment = {
|
||||
|
||||
describe('attachment rejection copy', () => {
|
||||
const limits = {
|
||||
maxImageBytes: 10 * 1024 * 1024,
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
@@ -47,7 +47,7 @@ describe('attachment rejection copy', () => {
|
||||
expect(attachmentErrorText(t, 'INVALID_IMAGE')).toBe('仅支持 PNG、JPG、WebP、GIF 格式的图片')
|
||||
expect(attachmentErrorText(t, 'IMAGE_TYPE_MISMATCH')).toBe('仅支持 PNG、JPG、WebP、GIF 格式的图片')
|
||||
expect(attachmentErrorText(t, 'TOO_MANY_IMAGES', limits)).toBe('一条消息最多添加 20 张图片')
|
||||
expect(attachmentErrorText(t, 'IMAGE_TOO_LARGE', limits)).toBe('单张图片不能超过 10MB')
|
||||
expect(attachmentErrorText(t, 'IMAGE_TOO_LARGE', limits)).toBe('单张图片不能超过 5MB')
|
||||
expect(attachmentErrorText(t, 'IMAGES_TOO_LARGE', limits)).toBe('图片总大小超过 100MB,请移除部分图片')
|
||||
expect(attachmentErrorText(enT, 'TOO_MANY_IMAGES', limits)).toBe('A message can include up to 20 images')
|
||||
})
|
||||
|
||||
@@ -323,7 +323,7 @@ describe('image draft rail', () => {
|
||||
const { view } = bench({
|
||||
addImages: vi.fn(() => null),
|
||||
imageLimits: {
|
||||
maxImageBytes: 10 * 1024 * 1024,
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
@@ -331,7 +331,7 @@ describe('image draft rail', () => {
|
||||
},
|
||||
})
|
||||
fireEvent.dragEnter(document.body, { dataTransfer: { types: ['Files'], files: [], dropEffect: 'none' } })
|
||||
expect(view.getByRole('status').textContent).toContain('最多 20 张,每张 10MB')
|
||||
expect(view.getByRole('status').textContent).toContain('最多 20 张,每张 5MB')
|
||||
})
|
||||
|
||||
it('announces server attachment rejections as product copy, other codes as developer text', () => {
|
||||
|
||||
@@ -90,7 +90,7 @@ describe('session.history projections block', () => {
|
||||
it('publishes the attachments imageLimits as a constant unit while both seams are composed', async () => {
|
||||
const { ctx, session } = await harness(true)
|
||||
const limits = {
|
||||
maxImageBytes: 10 * 1024 * 1024,
|
||||
maxImageBytes: 5 * 1024 * 1024,
|
||||
maxImagesPerMessage: 20,
|
||||
maxMessageImageBytes: 100 * 1024 * 1024,
|
||||
maxImagePixels: 40_000_000,
|
||||
|
||||
Reference in New Issue
Block a user