/** * Copyright 2026 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { getContext, run, z, type ActionContext, type Operation, } from '@genkit-ai/core'; import { type Registry } from '@genkit-ai/core/registry'; import { cancelOperation } from './cancel-operation.js'; import { checkOperation } from './check-operation.js'; import { type DocumentData } from './document.js'; import { embed, embedMany, type EmbedderArgument, type EmbedderParams, type Embedding, type EmbeddingBatch, } from './embedder.js'; import { generate, generateStream, type GenerateOptions, type GenerateResponse, type GenerateStreamOptions, type GenerateStreamResponse, } from './generate.js'; import { GenerationCommonConfigSchema, type Part } from './model-types.js'; /** * `GenkitAI` encapsulates Genkit's AI APIs. */ export class GenkitAI { readonly registry: Registry; constructor(registry: Registry) { this.registry = registry; } /** * Embeds the given `content` using the specified `embedder`. */ embed( params: EmbedderParams ): Promise { return embed(this.registry, params); } /** * A veneer for interacting with embedder models in bulk. */ embedMany(params: { embedder: EmbedderArgument; content: string[] | DocumentData[]; metadata?: Record; options?: z.infer; }): Promise { return embedMany(this.registry, params); } /** * Make a generate call to the default model with a simple text prompt. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * model: googleAI.model('gemini-flash-latest'), // default model * }) * * const { text } = await ai.generate('hi'); * ``` */ generate( strPrompt: string ): Promise>>; /** * Make a generate call to the default model with a multipart request. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * model: googleAI.model('gemini-flash-latest'), // default model * }) * * const { text } = await ai.generate([ * { media: {url: 'http://....'} }, * { text: 'describe this image' } * ]); * ``` */ generate( parts: Part[] ): Promise>>; /** * Generate calls a generative model based on the provided prompt and configuration. If * `messages` is provided, the generation will include a conversation history in its * request. If `tools` are provided, the generate method will automatically resolve * tool calls returned from the model unless `returnToolRequests` is set to `true`. * * See {@link GenerateOptions} for detailed information about available options. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * }) * * const { text } = await ai.generate({ * system: 'talk like a pirate', * prompt: [ * { media: { url: 'http://....' } }, * { text: 'describe this image' } * ], * messages: conversationHistory, * tools: [ userInfoLookup ], * model: googleAI.model('gemini-flash-latest'), * }); * ``` */ generate< O extends z.ZodTypeAny = z.ZodTypeAny, CustomOptions extends z.ZodTypeAny = typeof GenerationCommonConfigSchema, >( opts: | GenerateOptions | PromiseLike> ): Promise>>; async generate< O extends z.ZodTypeAny = z.ZodTypeAny, CustomOptions extends z.ZodTypeAny = typeof GenerationCommonConfigSchema, >( options: | string | Part[] | GenerateOptions | PromiseLike> ): Promise>> { let resolvedOptions: GenerateOptions; if (options instanceof Promise) { resolvedOptions = await options; } else if (typeof options === 'string' || Array.isArray(options)) { resolvedOptions = { prompt: options, }; } else { resolvedOptions = options as GenerateOptions; } return generate(this.registry, resolvedOptions); } /** * Make a streaming generate call to the default model with a simple text prompt. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * model: googleAI.model('gemini-flash-latest'), // default model * }) * * const { response, stream } = ai.generateStream('hi'); * for await (const chunk of stream) { * console.log(chunk.text); * } * console.log((await response).text); * ``` */ generateStream( strPrompt: string ): GenerateStreamResponse>; /** * Make a streaming generate call to the default model with a multipart request. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * model: googleAI.model('gemini-flash-latest'), // default model * }) * * const { response, stream } = ai.generateStream([ * { media: {url: 'http://....'} }, * { text: 'describe this image' } * ]); * for await (const chunk of stream) { * console.log(chunk.text); * } * console.log((await response).text); * ``` */ generateStream( parts: Part[] ): GenerateStreamResponse>; /** * Streaming generate calls a generative model based on the provided prompt and configuration. If * `messages` is provided, the generation will include a conversation history in its * request. If `tools` are provided, the generate method will automatically resolve * tool calls returned from the model unless `returnToolRequests` is set to `true`. * * See {@link GenerateOptions} for detailed information about available options. * * ```ts * const ai = genkit({ * plugins: [googleAI()], * }) * * const { response, stream } = ai.generateStream({ * system: 'talk like a pirate', * prompt: [ * { media: { url: 'http://....' } }, * { text: 'describe this image' } * ], * messages: conversationHistory, * tools: [ userInfoLookup ], * model: googleAI.model('gemini-flash-latest'), * }); * for await (const chunk of stream) { * console.log(chunk.text); * } * console.log((await response).text); * ``` */ generateStream< O extends z.ZodTypeAny = z.ZodTypeAny, CustomOptions extends z.ZodTypeAny = typeof GenerationCommonConfigSchema, >( opts: | GenerateStreamOptions | PromiseLike> ): GenerateStreamResponse>; generateStream< O extends z.ZodTypeAny = z.ZodTypeAny, CustomOptions extends z.ZodTypeAny = typeof GenerationCommonConfigSchema, >( options: | string | Part[] | GenerateStreamOptions | PromiseLike> ): GenerateStreamResponse> { if (typeof options === 'string' || Array.isArray(options)) { options = { prompt: options }; } return generateStream(this.registry, options); } /** * Checks the status of of a given operation. Returns a new operation which will contain the updated status. * * ```ts * let operation = await ai.generateOperation({ * model: googleAI.model('veo-2.0-generate-001'), * prompt: 'A banana riding a bicycle.', * }); * * while (!operation.done) { * operation = await ai.checkOperation(operation!); * await new Promise((resolve) => setTimeout(resolve, 5000)); * } * ``` * * @param operation * @returns */ checkOperation(operation: Operation): Promise> { return checkOperation(this.registry, operation); } /** * Cancels a given operation. Returns a new operation which will contain the updated status. * * @param operation * @returns */ cancelOperation(operation: Operation): Promise> { return cancelOperation(this.registry, operation); } /** * A flow step that executes the provided function. Each run step is recorded separately in the trace. * * ```ts * ai.defineFlow('hello', async() => { * await ai.run('step1', async () => { * // ... step 1 * }); * await ai.run('step2', async () => { * // ... step 2 * }); * return result; * }) * ``` */ run(name: string, func: () => Promise): Promise; /** * A flow step that executes the provided function. Each run step is recorded separately in the trace. * * ```ts * ai.defineFlow('hello', async(name) => { * const greeting = await ai.run('step1', name, async (input) => { * return `Hello, ${input}!`; * }); * const result = await ai.run('step2', greeting, async (input) => { * // ... step 2 * }); * return result; * }) */ run( name: string, input: any, func: (input?: any) => Promise ): Promise; run( name: string, funcOrInput: () => Promise | any, maybeFunc?: (input?: any) => Promise ): Promise { if (maybeFunc) { return run(name, funcOrInput, maybeFunc, this.registry); } return run(name, funcOrInput, this.registry); } /** * Returns current action (or flow) invocation context. Can be used to access things like auth * data set by HTTP server frameworks. If invoked outside of an action (e.g. flow or tool) will * return `undefined`. */ currentContext(): ActionContext | undefined { return getContext(); } }