diff --git a/js/src/client.ts b/js/src/client.ts index d9aa11ca4..31704d448 100644 --- a/js/src/client.ts +++ b/js/src/client.ts @@ -2770,6 +2770,7 @@ export class Client implements LangSmithTracingClientInterface { (acc, [key, value]) => { acc[key.slice("attachment.".length)] = { presigned_url: value.presigned_url, + mime_type: value.mime_type, }; return acc; }, @@ -2867,6 +2868,7 @@ export class Client implements LangSmithTracingClientInterface { (acc, [key, value]) => { acc[key.slice("attachment.".length)] = { presigned_url: value.presigned_url, + mime_type: value.mime_type || undefined, }; return acc; }, diff --git a/js/src/schemas.ts b/js/src/schemas.ts index 9fe4e8e16..d822e8392 100644 --- a/js/src/schemas.ts +++ b/js/src/schemas.ts @@ -65,6 +65,7 @@ export interface BaseExample { export interface AttachmentInfo { presigned_url: string; + mime_type?: string; } export type AttachmentData = Uint8Array | ArrayBuffer; @@ -300,6 +301,7 @@ export interface Example extends BaseExample { interface RawAttachmentInfo { presigned_url: string; s3_url: string; + mime_type?: string; } export interface RawExample extends BaseExample { id: string; diff --git a/js/src/tests/evaluate_attachments.int.test.ts b/js/src/tests/evaluate_attachments.int.test.ts index 0a64a54f9..8a359e0f5 100644 --- a/js/src/tests/evaluate_attachments.int.test.ts +++ b/js/src/tests/evaluate_attachments.int.test.ts @@ -34,18 +34,22 @@ test("evaluate can handle examples with attachments", async () => { config?: TargetConfigT ) => { // Verify we receive the attachment data - if (!config?.attachments?.["image"]) { + if (!config?.attachments?.image) { throw new Error("Image attachment not found"); } const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); + const attachmentMimeType = config?.attachments?.image.mime_type; + if (attachmentMimeType !== "image/png") { + throw new Error("Image attachment has incorrect mime type"); + } const attachmentData: Uint8Array | undefined = config?.attachments?.[ "image" ].presigned_url ? new Uint8Array( - (await fetch(config?.attachments?.["image"].presigned_url).then( - (res) => res.arrayBuffer() + (await fetch(config?.attachments?.image.presigned_url).then((res) => + res.arrayBuffer() )) as ArrayBuffer ) : undefined; @@ -57,14 +61,18 @@ test("evaluate can handle examples with attachments", async () => { const customEvaluator = async ({ attachments }: { attachments?: any }) => { expect(attachments).toBeDefined(); - expect(attachments?.["image"]).toBeDefined(); + expect(attachments?.image).toBeDefined(); const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); - const attachmentData: Uint8Array | undefined = attachments?.["image"] + const attachmentMimeType = attachments?.image.mime_type; + if (attachmentMimeType !== "image/png") { + throw new Error("Image attachment has incorrect mime type"); + } + const attachmentData: Uint8Array | undefined = attachments?.image .presigned_url ? new Uint8Array( - (await fetch(attachments?.["image"].presigned_url).then((res) => + (await fetch(attachments?.image.presigned_url).then((res) => res.arrayBuffer() )) as ArrayBuffer ) @@ -134,14 +142,14 @@ test("evaluate with attachments not in target function", async () => { const customEvaluator = async ({ attachments }: { attachments?: any }) => { expect(attachments).toBeDefined(); - expect(attachments?.["image"]).toBeDefined(); + expect(attachments?.image).toBeDefined(); const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); - const attachmentData: Uint8Array | undefined = attachments?.["image"] + const attachmentData: Uint8Array | undefined = attachments?.image .presigned_url ? new Uint8Array( - (await fetch(attachments?.["image"].presigned_url).then((res) => + (await fetch(attachments?.image.presigned_url).then((res) => res.arrayBuffer() )) as ArrayBuffer ) @@ -210,7 +218,7 @@ test("multiple evaluators with attachments", async () => { config?: TargetConfigT ) => { // Verify we receive the attachment data - if (!config?.attachments?.["image"]) { + if (!config?.attachments?.image) { throw new Error("Image attachment not found"); } const expectedData = new Uint8Array( @@ -220,8 +228,8 @@ test("multiple evaluators with attachments", async () => { "image" ].presigned_url ? new Uint8Array( - (await fetch(config?.attachments?.["image"].presigned_url).then( - (res) => res.arrayBuffer() + (await fetch(config?.attachments?.image.presigned_url).then((res) => + res.arrayBuffer() )) as ArrayBuffer ) : undefined; @@ -233,14 +241,14 @@ test("multiple evaluators with attachments", async () => { const customEvaluatorOne = async ({ attachments }: { attachments?: any }) => { expect(attachments).toBeDefined(); - expect(attachments?.["image"]).toBeDefined(); + expect(attachments?.image).toBeDefined(); const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); - const attachmentData: Uint8Array | undefined = attachments?.["image"] + const attachmentData: Uint8Array | undefined = attachments?.image .presigned_url ? new Uint8Array( - (await fetch(attachments?.["image"].presigned_url).then((res) => + (await fetch(attachments?.image.presigned_url).then((res) => res.arrayBuffer() )) as ArrayBuffer ) @@ -256,14 +264,14 @@ test("multiple evaluators with attachments", async () => { const customEvaluatorTwo = async ({ attachments }: { attachments?: any }) => { expect(attachments).toBeDefined(); - expect(attachments?.["image"]).toBeDefined(); + expect(attachments?.image).toBeDefined(); const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); - const attachmentData: Uint8Array | undefined = attachments?.["image"] + const attachmentData: Uint8Array | undefined = attachments?.image .presigned_url ? new Uint8Array( - (await fetch(attachments?.["image"].presigned_url).then((res) => + (await fetch(attachments?.image.presigned_url).then((res) => res.arrayBuffer() )) as ArrayBuffer ) @@ -329,7 +337,7 @@ test("evaluate with attachments runnable target function", async () => { await client.uploadExamplesMultipart(dataset.id, [example]); const myFunction = async (_input: any, config?: any) => { - if (!config?.attachments?.["image"]) { + if (!config?.attachments?.image) { throw new Error("Image attachment not found"); } const expectedData = new Uint8Array( @@ -339,8 +347,8 @@ test("evaluate with attachments runnable target function", async () => { "image" ].presigned_url ? new Uint8Array( - (await fetch(config?.attachments?.["image"].presigned_url).then( - (res) => res.arrayBuffer() + (await fetch(config?.attachments?.image.presigned_url).then((res) => + res.arrayBuffer() )) as ArrayBuffer ) : undefined; @@ -355,14 +363,14 @@ test("evaluate with attachments runnable target function", async () => { const customEvaluator = async ({ attachments }: { attachments?: any }) => { expect(attachments).toBeDefined(); - expect(attachments?.["image"]).toBeDefined(); + expect(attachments?.image).toBeDefined(); const expectedData = new Uint8Array( Buffer.from("fake image data for testing") ); - const attachmentData: Uint8Array | undefined = attachments?.["image"] + const attachmentData: Uint8Array | undefined = attachments?.image .presigned_url ? new Uint8Array( - (await fetch(attachments?.["image"].presigned_url).then((res) => + (await fetch(attachments?.image.presigned_url).then((res) => res.arrayBuffer() )) as ArrayBuffer )