Skip to content

Commit 194f85c

Browse files
authored
docs: update guidance on how to write a plugin (#1218)
1 parent bd1b7d6 commit 194f85c

File tree

3 files changed

+81
-62
lines changed

3 files changed

+81
-62
lines changed

‎docs/plugin-authoring-evaluator.md‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,14 @@ In this case we have two evaluators `DELICIOUSNESS` and `US_PHONE_REGEX_MATCH`.
262262

263263
```ts
264264
export function myAwesomeEval<ModelCustomOptions extends z.ZodTypeAny>(
265-
params: PluginOptions<ModelCustomOptions>
265+
options: PluginOptions<ModelCustomOptions>
266266
): PluginProvider {
267267
// Define the new plugin
268-
const plugin = genkitPlugin(
268+
const plugin = (options?: MyPluginOptions<ModelCustomOptions>) => {
269+
return genkitPlugin(
269270
'myAwesomeEval',
270-
async (params: PluginOptions<ModelCustomOptions>) => {
271-
const { judge, judgeConfig, metrics } = params;
271+
async (ai: Genkit) => {
272+
const { judge, judgeConfig, metrics } = options;
272273
const evaluators: EvaluatorAction[] = metrics.map((metric) => {
273274
// We'll create these functions in the next step
274275
switch (metric) {
@@ -281,11 +282,10 @@ export function myAwesomeEval<ModelCustomOptions extends z.ZodTypeAny>(
281282
}
282283
});
283284
return { evaluators };
284-
}
285-
);
286-
287-
// Create the plugin with the passed params
288-
return plugin(params);
285+
})
286+
}
287+
// Create the plugin with the passed options
288+
return plugin(options);
289289
}
290290
export default myAwesomeEval;
291291
```
@@ -299,7 +299,7 @@ For evaluation with Gemini, disable safety settings so that the evaluator can ac
299299
```ts
300300
import { gemini15Flash } from '@genkit-ai/googleai';
301301

302-
export default configureGenkit({
302+
const ai = genkit({
303303
plugins: [
304304
...
305305
myAwesomeEval({

‎docs/plugin-authoring-telemetry.md‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,19 @@ Logging is provided separately so that a plugin can control where the data is
3535
written explicitly.
3636

3737
```ts
38-
import { genkitPlugin, Plugin } from '@genkit-ai/core';
38+
import { Genkit } from 'genkit';
39+
import { genkitPlugin, GenkitPlugin } from'genkit/plugin';
40+
3941

4042
...
4143

4244
export interface MyPluginOptions {
4345
// [Optional] Your plugin options
4446
}
4547

46-
export const myPlugin: Plugin<[MyPluginOptions] | []> = genkitPlugin(
48+
export const myPlugin: GenkitPlugin<[MyPluginOptions] | []> = genkitPlugin(
4749
'myPlugin',
48-
async (options?: MyPluginOptions) => {
50+
async (ai: Genkit) => {
4951
return {
5052
telemetry: {
5153
instrumentation: {
@@ -226,6 +228,7 @@ The following is a full example of the telemetry plugin created above. For
226228
a real world example, take a look at the `@genkit-ai/google-cloud` plugin.
227229

228230
```ts
231+
import { genkitPlugin, GenkitPlugin } from 'genkit/plugin';
229232
import {
230233
genkitPlugin,
231234
LoggerConfig,
@@ -293,9 +296,11 @@ const myLogger: LoggerConfig = {
293296
},
294297
};
295298

296-
export const myPlugin: Plugin<[MyPluginOptions] | []> = genkitPlugin(
297-
'myPlugin',
298-
async (options?: MyPluginOptions) => {
299+
export function myPlugin(options?: MyPluginOptions) {
300+
return genkitPlugin('myPlugin', async (ai: Genkit) => {
301+
ai.defineModel(...);
302+
ai.defineEmbedder(...)
303+
// ....
299304
return {
300305
telemetry: {
301306
instrumentation: {
@@ -308,8 +313,8 @@ export const myPlugin: Plugin<[MyPluginOptions] | []> = genkitPlugin(
308313
},
309314
},
310315
};
311-
}
312-
);
316+
});
317+
};
313318

314319
export default myPlugin;
315320
```

‎docs/plugin-authoring.md‎

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ cd genkitx-my-plugin
3030
3131
npm init -y
3232
33-
npm i --save @genkit-ai/core
33+
npm i --save genkit
3434
3535
npm i --save-dev typescript
3636
@@ -46,12 +46,17 @@ interface MyPluginOptions {
4646
// add any plugin configuration here
4747
}
4848

49-
export const myPlugin = genkitPlugin(
50-
'my-plugin',
51-
async (options: MyPluginOptions) => {
52-
// initialize your plugin here...
53-
}
54-
);
49+
import { Genkit, z } from 'genkit';
50+
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';
51+
52+
export function myPlugin(options?: MyPluginOptions) {
53+
return genkitPlugin('myPlugin', async (ai: Genkit) => {
54+
ai.defineModel(...);
55+
ai.defineEmbedder(...)
56+
// ....
57+
});
58+
};
59+
5560
```
5661

5762
### Plugin options guidance
@@ -62,26 +67,30 @@ requires a secret value, such as API keys, you should offer both an option and a
6267
default environment variable to configure it:
6368

6469
```ts
65-
import { genkitPlugin, GenkitError } from '@genkit-ai/core';
70+
import { Genkit, z } from 'genkit';
71+
import { GenkitPlugin, genkitPlugin } from 'genkit/plugin';
72+
import { GenkitError } from '@genkit-ai/core';
6673

6774
interface MyPluginOptions {
6875
apiKey?: string;
6976
}
7077

71-
export const myPlugin = genkitPlugin(
72-
'my-plugin',
73-
async (options: MyPluginOptions) => {
74-
const apiKey = options.apiKey || process.env.MY_PLUGIN_API_KEY;
78+
export function myPlugin(options?: MyPluginOptions) {
79+
return genkitPlugin('myPlugin', async (ai: Genkit) => {
7580
if (!apiKey)
7681
throw new GenkitError({
7782
source: 'my-plugin',
7883
status: 'INVALID_ARGUMENT',
7984
message:
8085
'Must supply either `options.apiKey` or set `MY_PLUGIN_API_KEY` environment variable.',
8186
});
82-
// ... continue initialization
83-
}
84-
);
87+
88+
ai.defineModel(...);
89+
ai.defineEmbedder(...)
90+
91+
// ....
92+
});
93+
};
8594
```
8695

8796
## Building your plugin
@@ -110,39 +119,44 @@ npm i --save @genkit-ai/ai
110119
At a high level, a model plugin might look something like this:
111120

112121
```ts
113-
import { genkitPlugin, GenkitError } from '@genkit-ai/core';
114-
import { defineModel, GenerationCommonConfigSchema } from '@genkit-ai/ai/model';
122+
import { genkitPlugin, GenkitPlugin } from 'genkit/plugin';
123+
import { GenkitError } from '@genkit-ai/core';
124+
import { GenerationCommonConfigSchema } from '@genkit-ai/ai/model';
115125
import { simulateSystemPrompt } from '@genkit-ai/ai/model/middleware';
116126
import { z } from 'zod';
117127

118-
export const myPlugin = genkitPlugin('my-plugin', async (options: {apiKey?: string}) => {
119-
defineModel({
120-
// be sure to include your plugin as a provider prefix
121-
name: 'my-plugin/my-model',
122-
// label for your model as shown in Genkit Developer UI
123-
label: 'My Awesome Model',
124-
// optional list of supported versions of your model
125-
versions: ['my-model-001', 'my-model-001'],
126-
// model support attributes
127-
supports: {
128-
multiturn: true, // true if your model supports conversations
129-
media: true, // true if your model supports multimodal input
130-
tools: true, // true if your model supports tool/function calling
131-
systemRole: true, // true if your model supports the system role
132-
output: ['text', 'media', 'json'], // types of output your model supports
133-
},
134-
// Zod schema for your model's custom configuration
135-
configSchema: GenerationCommonConfigSchema.extend({
136-
safetySettings: z.object({...}),
137-
}),
138-
// list of middleware for your model to use
139-
use: [simulateSystemPrompt()]
140-
}, async request => {
141-
const myModelRequest = toMyModelRequest(request);
142-
const myModelResponse = await myModelApi(myModelRequest);
143-
return toGenerateResponse(myModelResponse);
128+
export function myPlugin(options?: MyPluginOptions) {
129+
return genkitPlugin('my-plugin', async (ai: Genkit) => {
130+
ai.defineModel({
131+
// be sure to include your plugin as a provider prefix
132+
name: 'my-plugin/my-model',
133+
// label for your model as shown in Genkit Developer UI
134+
label: 'My Awesome Model',
135+
// optional list of supported versions of your model
136+
versions: ['my-model-001', 'my-model-001'],
137+
// model support attributes
138+
supports: {
139+
multiturn: true, // true if your model supports conversations
140+
media: true, // true if your model supports multimodal input
141+
tools: true, // true if your model supports tool/function calling
142+
systemRole: true, // true if your model supports the system role
143+
output: ['text', 'media', 'json'], // types of output your model supports
144+
},
145+
// Zod schema for your model's custom configuration
146+
configSchema: GenerationCommonConfigSchema.extend({
147+
safetySettings: z.object({...}),
148+
}),
149+
// list of middleware for your model to use
150+
use: [simulateSystemPrompt()]
151+
}, async request => {
152+
const myModelRequest = toMyModelRequest(request);
153+
const myModelResponse = await myModelApi(myModelRequest);
154+
return toGenerateResponse(myModelResponse);
155+
});
144156
});
145-
});
157+
};
158+
159+
146160
```
147161

148162
#### Transforming Requests and Responses

0 commit comments

Comments
 (0)