@genkit-ai/vertexai
Version:
Genkit AI framework plugin for Google Cloud Vertex AI APIs including Gemini APIs, Imagen, and more.
381 lines • 10.5 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var anthropic_exports = {};
__export(anthropic_exports, {
AnthropicConfigSchema: () => AnthropicConfigSchema,
SUPPORTED_ANTHROPIC_MODELS: () => SUPPORTED_ANTHROPIC_MODELS,
anthropicModel: () => anthropicModel,
claude35Sonnet: () => claude35Sonnet,
claude35SonnetV2: () => claude35SonnetV2,
claude3Haiku: () => claude3Haiku,
claude3Opus: () => claude3Opus,
claude3Sonnet: () => claude3Sonnet,
fromAnthropicResponse: () => fromAnthropicResponse,
toAnthropicRequest: () => toAnthropicRequest
});
module.exports = __toCommonJS(anthropic_exports);
var import_vertex_sdk = require("@anthropic-ai/vertex-sdk");
var import_genkit = require("genkit");
var import_model = require("genkit/model");
const AnthropicConfigSchema = import_model.GenerationCommonConfigSchema.extend({
location: import_genkit.z.string().optional()
});
const claude35SonnetV2 = (0, import_model.modelRef)({
name: "vertexai/claude-3-5-sonnet-v2",
info: {
label: "Vertex AI Model Garden - Claude 3.5 Sonnet",
versions: ["claude-3-5-sonnet-v2@20241022"],
supports: {
multiturn: true,
media: true,
tools: true,
systemRole: true,
output: ["text"]
}
},
configSchema: AnthropicConfigSchema
});
const claude35Sonnet = (0, import_model.modelRef)({
name: "vertexai/claude-3-5-sonnet",
info: {
label: "Vertex AI Model Garden - Claude 3.5 Sonnet",
versions: ["claude-3-5-sonnet@20240620"],
supports: {
multiturn: true,
media: true,
tools: true,
systemRole: true,
output: ["text"]
}
},
configSchema: AnthropicConfigSchema
});
const claude3Sonnet = (0, import_model.modelRef)({
name: "vertexai/claude-3-sonnet",
info: {
label: "Vertex AI Model Garden - Claude 3 Sonnet",
versions: ["claude-3-sonnet@20240229"],
supports: {
multiturn: true,
media: true,
tools: true,
systemRole: true,
output: ["text"]
}
},
configSchema: AnthropicConfigSchema
});
const claude3Haiku = (0, import_model.modelRef)({
name: "vertexai/claude-3-haiku",
info: {
label: "Vertex AI Model Garden - Claude 3 Haiku",
versions: ["claude-3-haiku@20240307"],
supports: {
multiturn: true,
media: true,
tools: true,
systemRole: true,
output: ["text"]
}
},
configSchema: AnthropicConfigSchema
});
const claude3Opus = (0, import_model.modelRef)({
name: "vertexai/claude-3-opus",
info: {
label: "Vertex AI Model Garden - Claude 3 Opus",
versions: ["claude-3-opus@20240229"],
supports: {
multiturn: true,
media: true,
tools: true,
systemRole: true,
output: ["text"]
}
},
configSchema: AnthropicConfigSchema
});
const SUPPORTED_ANTHROPIC_MODELS = {
"claude-3-5-sonnet-v2": claude35SonnetV2,
"claude-3-5-sonnet": claude35Sonnet,
"claude-3-sonnet": claude3Sonnet,
"claude-3-opus": claude3Opus,
"claude-3-haiku": claude3Haiku
};
function toAnthropicRequest(model, input) {
let system = void 0;
const messages = [];
for (const msg of input.messages) {
if (msg.role === "system") {
system = msg.content.map((c) => {
if (!c.text) {
throw new Error(
"Only text context is supported for system messages."
);
}
return c.text;
}).join();
} else if (msg.content[msg.content.length - 1].toolResponse) {
messages.push({
role: "user",
content: toAnthropicContent(msg.content)
});
} else {
messages.push({
role: toAnthropicRole(msg.role),
content: toAnthropicContent(msg.content)
});
}
}
const request = {
model,
messages,
// https://docs.anthropic.com/claude/docs/models-overview#model-comparison
max_tokens: input.config?.maxOutputTokens ?? 4096
};
if (system) {
request["system"] = system;
}
if (input.tools) {
request.tools = input.tools?.map((tool) => {
return {
name: tool.name,
description: tool.description,
input_schema: tool.inputSchema
};
});
}
if (input.config?.stopSequences) {
request.stop_sequences = input.config?.stopSequences;
}
if (input.config?.temperature) {
request.temperature = input.config?.temperature;
}
if (input.config?.topK) {
request.top_k = input.config?.topK;
}
if (input.config?.topP) {
request.top_p = input.config?.topP;
}
return request;
}
function toAnthropicContent(content) {
return content.map((p) => {
if (p.text) {
return {
type: "text",
text: p.text
};
}
if (p.media) {
let b64Data = p.media.url;
if (b64Data.startsWith("data:")) {
b64Data = b64Data.substring(b64Data.indexOf(",") + 1);
}
return {
type: "image",
source: {
type: "base64",
data: b64Data,
media_type: p.media.contentType
}
};
}
if (p.toolRequest) {
return toAnthropicToolRequest(p.toolRequest);
}
if (p.toolResponse) {
return toAnthropicToolResponse(p);
}
throw new Error(`Unsupported content type: ${JSON.stringify(p)}`);
});
}
function toAnthropicRole(role) {
if (role === "model") {
return "assistant";
}
if (role === "user") {
return "user";
}
if (role === "tool") {
return "assistant";
}
throw new Error(`Unsupported role type ${role}`);
}
function fromAnthropicTextPart(part) {
return {
text: part.text
};
}
function fromAnthropicToolCallPart(part) {
return {
toolRequest: {
name: part.name,
input: part.input,
ref: part.id
}
};
}
function fromAnthropicPart(part) {
if (part.type === "text") return fromAnthropicTextPart(part);
if (part.type === "tool_use") return fromAnthropicToolCallPart(part);
throw new Error(
"Part type is unsupported/corrupted. Either data is missing or type cannot be inferred from type."
);
}
function fromAnthropicResponse(input, response) {
const parts = response.content;
const message = {
role: "model",
content: parts.map(fromAnthropicPart)
};
return {
message,
finishReason: toGenkitFinishReason(
response.stop_reason
),
custom: {
id: response.id,
model: response.model,
type: response.type
},
usage: {
...(0, import_model.getBasicUsageStats)(input.messages, message),
inputTokens: response.usage.input_tokens,
outputTokens: response.usage.output_tokens
}
};
}
function toGenkitFinishReason(reason) {
switch (reason) {
case "end_turn":
return "stop";
case "max_tokens":
return "length";
case "stop_sequence":
return "stop";
case "tool_use":
return "stop";
case null:
return "unknown";
default:
return "other";
}
}
function toAnthropicToolRequest(tool) {
if (!tool.name) {
throw new Error("Tool name is required");
}
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(tool.name)) {
throw new Error(
`Tool name ${tool.name} contains invalid characters.
Only letters, numbers, and underscores are allowed,
and the name must be between 1 and 64 characters long.`
);
}
const declaration = {
type: "tool_use",
id: tool.ref,
name: tool.name,
input: tool.input
};
return declaration;
}
function toAnthropicToolResponse(part) {
if (!part.toolResponse?.ref) {
throw new Error("Tool response reference is required");
}
if (!part.toolResponse.output) {
throw new Error("Tool response output is required");
}
return {
type: "tool_result",
tool_use_id: part.toolResponse.ref,
content: JSON.stringify(part.toolResponse.output)
};
}
function anthropicModel(ai, modelName, projectId, region) {
const clients = {};
const clientFactory = (region2) => {
if (!clients[region2]) {
clients[region2] = new import_vertex_sdk.AnthropicVertex({
region: region2,
projectId,
defaultHeaders: {
"X-Goog-Api-Client": import_genkit.GENKIT_CLIENT_HEADER
}
});
}
return clients[region2];
};
const model = SUPPORTED_ANTHROPIC_MODELS[modelName];
if (!model) {
throw new Error(`unsupported Anthropic model name ${modelName}`);
}
return ai.defineModel(
{
name: model.name,
label: model.info?.label,
configSchema: AnthropicConfigSchema,
supports: model.info?.supports,
versions: model.info?.versions
},
async (input, sendChunk) => {
const client = clientFactory(input.config?.location || region);
if (!sendChunk) {
const response = await client.messages.create({
...toAnthropicRequest(input.config?.version ?? modelName, input),
stream: false
});
return fromAnthropicResponse(input, response);
} else {
const stream = await client.messages.stream(
toAnthropicRequest(input.config?.version ?? modelName, input)
);
for await (const event of stream) {
if (event.type === "content_block_delta") {
sendChunk({
index: 0,
content: [
{
text: event.delta.text
}
]
});
}
}
return fromAnthropicResponse(input, await stream.finalMessage());
}
}
);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
AnthropicConfigSchema,
SUPPORTED_ANTHROPIC_MODELS,
anthropicModel,
claude35Sonnet,
claude35SonnetV2,
claude3Haiku,
claude3Opus,
claude3Sonnet,
fromAnthropicResponse,
toAnthropicRequest
});
//# sourceMappingURL=anthropic.js.map