@genkit-ai/ai
Version:
Genkit AI framework generative AI APIs.
155 lines • 4.88 kB
JavaScript
import { parseSchema } from "@genkit-ai/core/schema";
import {
GenerationBlockedError,
GenerationResponseError
} from "../generate.js";
import { Message } from "../message.js";
class GenerateResponse {
/** The generated message. */
message;
/** The reason generation stopped for this request. */
finishReason;
/** Additional information about why the model stopped generating, if any. */
finishMessage;
/** Usage information. */
usage;
/** Provider-specific response data. */
custom;
/** The request that generated this response. */
request;
/** The parser for output parsing of this response. */
parser;
constructor(response, options) {
const generatedMessage = response.message || response.candidates?.[0]?.message;
if (generatedMessage) {
this.message = new Message(generatedMessage, {
parser: options?.parser
});
}
this.finishReason = response.finishReason || response.candidates?.[0]?.finishReason;
this.finishMessage = response.finishMessage || response.candidates?.[0]?.finishMessage;
this.usage = response.usage || {};
this.custom = response.custom || {};
this.request = options?.request;
}
/**
* Throws an error if the response does not contain valid output.
*/
assertValid() {
if (this.finishReason === "blocked") {
throw new GenerationBlockedError(
this,
`Generation blocked${this.finishMessage ? `: ${this.finishMessage}` : "."}`
);
}
if (!this.message) {
throw new GenerationResponseError(
this,
`Model did not generate a message. Finish reason: '${this.finishReason}': ${this.finishMessage}`
);
}
}
/**
* Throws an error if the response does not conform to expected schema.
*/
assertValidSchema(request) {
if (request?.output?.schema || this.request?.output?.schema) {
const o = this.output;
parseSchema(o, {
jsonSchema: request?.output?.schema || this.request?.output?.schema
});
}
}
isValid(request) {
try {
this.assertValid();
this.assertValidSchema(request);
return true;
} catch (e) {
return false;
}
}
/**
* If the generated message contains a `data` part, it is returned. Otherwise,
* the `output()` method extracts the first valid JSON object or array from the text
* contained in the selected candidate's message and returns it.
*
* @returns The structured output contained in the selected candidate.
*/
get output() {
return this.message?.output || null;
}
/**
* Concatenates all `text` parts present in the generated message with no delimiter.
* @returns A string of all concatenated text parts.
*/
get text() {
return this.message?.text || "";
}
/**
* Returns the first detected media part in the generated message. Useful for
* extracting (for example) an image from a generation expected to create one.
* @returns The first detected `media` part in the candidate.
*/
get media() {
return this.message?.media || null;
}
/**
* Returns the first detected `data` part of the generated message.
* @returns The first `data` part detected in the candidate (if any).
*/
get data() {
return this.message?.data || null;
}
/**
* Returns all tool request found in the generated message.
* @returns Array of all tool request found in the candidate.
*/
get toolRequests() {
return this.message?.toolRequests || [];
}
/**
* Returns all tool requests annotated as interrupts found in the generated message.
* @returns A list of ToolRequestParts.
*/
get interrupts() {
return this.message?.interrupts || [];
}
/**
* Returns the message history for the request by concatenating the model
* response to the list of messages from the request. The result of this
* method can be safely serialized to JSON for persistence in a database.
* @returns A serializable list of messages compatible with `generate({history})`.
*/
get messages() {
if (!this.request)
throw new Error(
"Can't construct history for response without request reference."
);
if (!this.message)
throw new Error(
"Can't construct history for response without generated message."
);
return [...this.request?.messages, this.message.toJSON()];
}
get raw() {
return this.raw ?? this.custom;
}
toJSON() {
const out = {
message: this.message?.toJSON(),
finishReason: this.finishReason,
finishMessage: this.finishMessage,
usage: this.usage,
custom: this.custom.toJSON?.() || this.custom,
request: this.request
};
if (!out.finishMessage) delete out.finishMessage;
if (!out.request) delete out.request;
return out;
}
}
export {
GenerateResponse
};
//# sourceMappingURL=response.mjs.map