diff --git a/genkit-tools/common/src/manager/manager.ts b/genkit-tools/common/src/manager/manager.ts index 7b20698644..3cb243c31f 100644 --- a/genkit-tools/common/src/manager/manager.ts +++ b/genkit-tools/common/src/manager/manager.ts @@ -198,6 +198,32 @@ export class RuntimeManager { return response.data as Record; } + /** + * Retrieves all valuess. + */ + async listValues( + input: apis.ListValuesRequest + ): Promise> { + const runtime = input.runtimeId + ? this.getRuntimeById(input.runtimeId) + : this.getMostRecentRuntime(); + if (!runtime) { + throw new Error( + input?.runtimeId + ? `No runtime found with ID ${input.runtimeId}.` + : 'No runtimes found. Make sure your app is running using `genkit start -- ...`. See getting started documentation.' + ); + } + const response = await axios + .get(`${runtime.reflectionServerUrl}/api/values`, { + params: { + type: input.type, + }, + }) + .catch((err) => this.httpErrorHandler(err, 'Error listing values.')); + return response.data as Record; + } + /** * Runs an action. */ diff --git a/genkit-tools/common/src/server/router.ts b/genkit-tools/common/src/server/router.ts index aa3cf30555..e85a374c07 100644 --- a/genkit-tools/common/src/server/router.ts +++ b/genkit-tools/common/src/server/router.ts @@ -134,6 +134,13 @@ export const TOOLS_SERVER_ROUTER = (manager: RuntimeManager) => return manager.listActions(input); }), + /** Retrieves all values. */ + listValues: loggedProcedure + .input(apis.ListValuesRequestSchema) + .query(async ({ input }): Promise> => { + return manager.listValues(input); + }), + /** Generate a .prompt file from messages and model config. */ createPrompt: loggedProcedure .input(apis.CreatePromptRequestSchema) diff --git a/genkit-tools/common/src/types/apis.ts b/genkit-tools/common/src/types/apis.ts index 4920f6ec65..8c8a980ff9 100644 --- a/genkit-tools/common/src/types/apis.ts +++ b/genkit-tools/common/src/types/apis.ts @@ -80,6 +80,22 @@ export const ListActionsRequestSchema = z export type ListActionsRequest = z.infer; +export const ListValuesRequestSchema = z.object({ + runtimeId: z + .string() + .optional() + .describe( + 'ID of the Genkit runtime to run the action on. Typically $pid-$port.' + ), + type: z + .enum(['defaultModel']) + .describe( + "The type of values to fetch. Currently only supports 'defaultModel'" + ), +}); + +export type ListValuesRequest = z.infer; + export const RunActionRequestSchema = z.object({ runtimeId: z .string() diff --git a/js/core/src/reflection.ts b/js/core/src/reflection.ts index 9b9389ad9d..b537f975f3 100644 --- a/js/core/src/reflection.ts +++ b/js/core/src/reflection.ts @@ -151,6 +151,22 @@ export class ReflectionServer { await this.stop(); }); + server.get('/api/values', async (req, response, next) => { + logger.debug('Fetching values.'); + try { + const type = req.query.type; + if (!type) { + response.status(400).send('Query parameter "type" is required.'); + return; + } + const values = await this.registry.listValues(type as string); + response.send(values); + } catch (err) { + const { message, stack } = err as Error; + next({ message, stack }); + } + }); + server.get('/api/actions', async (_, response, next) => { logger.debug('Fetching actions.'); try { diff --git a/js/genkit/src/genkit.ts b/js/genkit/src/genkit.ts index 2cd34a4c7a..41511b47a8 100644 --- a/js/genkit/src/genkit.ts +++ b/js/genkit/src/genkit.ts @@ -46,6 +46,7 @@ import { type GenerationCommonConfigSchema, type IndexerParams, type ModelArgument, + type ModelReference, type Part, type PromptConfig, type PromptGenerateOptions, @@ -953,7 +954,7 @@ export class Genkit implements HasRegistry { this.registry.registerValue( 'defaultModel', 'defaultModel', - this.options.model + modelName(this.options.model) ); } if (this.options.promptDir !== null) { @@ -1086,3 +1087,19 @@ let disableReflectionApi = false; export function __disableReflectionApi() { disableReflectionApi = true; } + +/** Helper method to map ModelArgument to string */ +function modelName( + modelArg: ModelArgument | undefined +): string | undefined { + if (modelArg === undefined) { + return undefined; + } + if (typeof modelArg === 'string') { + return modelArg; + } + if ((modelArg as ModelReference).name) { + return (modelArg as ModelReference).name; + } + return (modelArg as ModelAction).__action.name; +}