feat: implement proxy input file resolution and storage
- Added `inputFiles.ts` for handling input file resolution, including validation and normalization of file types. - Introduced `proxyFileStore.ts` for managing file storage, retrieval, and deletion with owner-based isolation. - Created tests for proxy file storage functionality in `proxyFileStore.test.ts`. - Developed `proxyInputFileResolver.ts` to resolve input files in OpenAI and response formats. - Added utility functions for handling reasoning signatures in `reasoningTransport.ts` and corresponding tests. - Enhanced shared input file transformers in `inputFile.ts` for better file handling and type inference.
This commit is contained in:
1 parent
ede8998244
commit
7bd3114ea0
54 files changed
+4504
-164
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const getProxyFileByPublicIdForOwnerMock = vi.fn();
|
||||
|
||||
vi.mock('./proxyFileStore.js', () => ({
|
||||
getProxyFileByPublicIdForOwner: (...args: unknown[]) => getProxyFileByPublicIdForOwnerMock(...args),
|
||||
LOCAL_PROXY_FILE_ID_PREFIX: 'file-metapi-',
|
||||
}));
|
||||
|
||||
describe('proxyInputFileResolver', () => {
|
||||
beforeEach(() => {
|
||||
getProxyFileByPublicIdForOwnerMock.mockReset();
|
||||
});
|
||||
|
||||
it('preserves non-local file ids without resolving them from the local store', async () => {
|
||||
const { resolveResponsesBodyInputFiles } = await import('./proxyInputFileResolver.js');
|
||||
const body = {
|
||||
model: 'gpt-5',
|
||||
input: [
|
||||
{
|
||||
type: 'message',
|
||||
role: 'user',
|
||||
content: [
|
||||
{
|
||||
type: 'input_file',
|
||||
file_id: 'file_external_123',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
await expect(resolveResponsesBodyInputFiles(
|
||||
body,
|
||||
{ ownerType: 'global_proxy_token', ownerId: 'global' },
|
||||
)).resolves.toEqual(body);
|
||||
expect(getProxyFileByPublicIdForOwnerMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('resolves object-form responses input payloads with local file ids', async () => {
|
||||
getProxyFileByPublicIdForOwnerMock.mockResolvedValue({
|
||||
publicId: 'file-metapi-123',
|
||||
filename: 'brief.pdf',
|
||||
mimeType: 'application/pdf',
|
||||
contentBase64: Buffer.from('%PDF-local').toString('base64'),
|
||||
});
|
||||
|
||||
const { resolveResponsesBodyInputFiles } = await import('./proxyInputFileResolver.js');
|
||||
await expect(resolveResponsesBodyInputFiles(
|
||||
{
|
||||
model: 'gpt-5',
|
||||
input: {
|
||||
type: 'message',
|
||||
role: 'user',
|
||||
content: [
|
||||
{
|
||||
type: 'input_file',
|
||||
file_id: 'file-metapi-123',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{ ownerType: 'managed_key', ownerId: '9' },
|
||||
)).resolves.toEqual({
|
||||
model: 'gpt-5',
|
||||
input: {
|
||||
type: 'message',
|
||||
role: 'user',
|
||||
content: [
|
||||
{
|
||||
type: 'input_file',
|
||||
file_id: 'file-metapi-123',
|
||||
filename: 'brief.pdf',
|
||||
file_data: Buffer.from('%PDF-local').toString('base64'),
|
||||
mime_type: 'application/pdf',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user