diff --git a/js/ai/src/generate/response.ts b/js/ai/src/generate/response.ts index 54fcb7c1b7..85d36fa5dc 100644 --- a/js/ai/src/generate/response.ts +++ b/js/ai/src/generate/response.ts @@ -67,6 +67,20 @@ export class GenerateResponse implements ModelResponseData { const generatedMessage = response.message || response.candidates?.[0]?.message; if (generatedMessage) { + if ( + options?.request?.output?.contentType || + options?.request?.output?.format + ) { + generatedMessage.metadata = { + ...generatedMessage.metadata, + generate: { + output: { + contentType: options?.request?.output?.contentType, + format: options?.request?.output?.format, + }, + }, + }; + } this.message = new Message(generatedMessage, { parser: options?.parser, }); diff --git a/js/ai/tests/generate/response_test.ts b/js/ai/tests/generate/response_test.ts index 130bb1cea5..cb4333b8b6 100644 --- a/js/ai/tests/generate/response_test.ts +++ b/js/ai/tests/generate/response_test.ts @@ -244,4 +244,40 @@ describe('GenerateResponse', () => { assert.deepStrictEqual(response.toolRequests, [toolCall1, toolCall2]); }); }); + + it('returns metadata for output conformance', () => { + const request: GenerateRequest = { + messages: [], + output: { + constrained: true, + format: 'json', + contentType: 'application/json', + schema: toJsonSchema({ + schema: z.object({ + name: z.string(), + age: z.number(), + }), + }), + }, + }; + + const response = new GenerateResponse( + { + message: { + role: 'model', + content: [{ text: '{"name": "John", "age": "30"}' }], + }, + finishReason: 'stop', + }, + { + request, + } + ); + + assert.deepEqual(response.message?.metadata, { + generate: { + output: { contentType: 'application/json', format: 'json' }, + }, + }); + }); });