Skip to content

Commit 12b392f

Browse files
authored
refactor(js/plugins): switch to implicit namespacing of actions in v2 plugin api (#3436)
1 parent e3defae commit 12b392f

File tree

5 files changed

+76
-14
lines changed

5 files changed

+76
-14
lines changed

js/core/src/background-action.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,20 +246,24 @@ export function defineBackgroundAction<
246246

247247
export function registerBackgroundAction(
248248
registry: Registry,
249-
act: BackgroundAction<any, any>
249+
act: BackgroundAction<any, any>,
250+
opts?: { namespace?: string }
250251
) {
251252
registry.registerAction(
252253
act.startAction.__action.actionType!,
253-
act.startAction
254+
act.startAction,
255+
opts
254256
);
255257
registry.registerAction(
256258
act.checkAction.__action.actionType!,
257-
act.checkAction
259+
act.checkAction,
260+
opts
258261
);
259262
if (act.cancelAction) {
260263
registry.registerAction(
261264
act.cancelAction.__action.actionType!,
262-
act.cancelAction
265+
act.cancelAction,
266+
opts
263267
);
264268
}
265269
}

js/core/src/registry.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,21 @@ export class Registry {
207207
*/
208208
registerAction<I extends z.ZodTypeAny, O extends z.ZodTypeAny>(
209209
type: ActionType,
210-
action: Action<I, O>
210+
action: Action<I, O>,
211+
opts?: { namespace?: string }
211212
) {
212213
if (type !== action.__action.actionType) {
213214
throw new GenkitError({
214215
status: 'INVALID_ARGUMENT',
215216
message: `action type (${type}) does not match type on action (${action.__action.actionType})`,
216217
});
217218
}
219+
if (
220+
opts?.namespace &&
221+
!action.__action.name.startsWith(`${opts.namespace}/`)
222+
) {
223+
action.__action.name = `${opts.namespace}/${action.__action.name}`;
224+
}
218225
const key = `/${type}/${action.__action.name}`;
219226
logger.debug(`registering ${key}`);
220227
if (this.actionsById.hasOwnProperty(key)) {
@@ -236,8 +243,12 @@ export class Registry {
236243
registerActionAsync<I extends z.ZodTypeAny, O extends z.ZodTypeAny>(
237244
type: ActionType,
238245
name: string,
239-
action: PromiseLike<Action<I, O>>
246+
action: PromiseLike<Action<I, O>>,
247+
opts?: { namespace?: string }
240248
) {
249+
if (opts?.namespace && !name.startsWith(`${opts.namespace}/`)) {
250+
name = `${opts.namespace}/${name}`;
251+
}
241252
const key = `/${type}/${name}`;
242253
logger.debug(`registering ${key} (async)`);
243254
if (this.actionsById.hasOwnProperty(key)) {

js/core/tests/registry_test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,43 @@ describe('registry class', () => {
407407
);
408408
});
409409

410+
it('returns registered action with namespace', async () => {
411+
const fooSomethingAction = action(
412+
{ name: 'foo_something', actionType: 'model' },
413+
async () => null
414+
);
415+
registry.registerAction('model', fooSomethingAction, {
416+
namespace: 'my-plugin',
417+
});
418+
const barSomethingAction = action(
419+
{ name: 'my-plugin/bar_something', actionType: 'model' },
420+
async () => null
421+
);
422+
registry.registerAction('model', barSomethingAction, {
423+
namespace: 'my-plugin',
424+
});
425+
const barSubSomethingAction = action(
426+
{ name: 'sub/bar_something', actionType: 'model' },
427+
async () => null
428+
);
429+
registry.registerAction('model', barSubSomethingAction, {
430+
namespace: 'my-plugin',
431+
});
432+
433+
assert.strictEqual(
434+
await registry.lookupAction('/model/my-plugin/foo_something'),
435+
fooSomethingAction
436+
);
437+
assert.strictEqual(
438+
await registry.lookupAction('/model/my-plugin/bar_something'),
439+
barSomethingAction
440+
);
441+
assert.strictEqual(
442+
await registry.lookupAction('/model/my-plugin/sub/bar_something'),
443+
barSubSomethingAction
444+
);
445+
});
446+
410447
it('returns action registered by plugin', async () => {
411448
registry.registerPluginProvider('foo', {
412449
name: 'foo',

js/genkit/src/genkit.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,11 @@ export class Genkit implements HasRegistry {
945945
},
946946
async listActions() {
947947
if (typeof plugin.list === 'function') {
948-
return await plugin.list();
948+
return (await plugin.list()).map((a) => ({
949+
...a,
950+
// Apply namespace for v2 plugins.
951+
name: `${plugin.name}/${a.name}`,
952+
}));
949953
}
950954
return [];
951955
},
@@ -990,15 +994,21 @@ function registerActionV2(
990994
plugin: GenkitPluginV2
991995
) {
992996
if (isBackgroundAction(resolvedAction)) {
993-
registerBackgroundAction(registry, resolvedAction);
997+
registerBackgroundAction(registry, resolvedAction, {
998+
namespace: plugin.name,
999+
});
9941000
} else if (isAction(resolvedAction)) {
9951001
if (!resolvedAction.__action.actionType) {
9961002
throw new GenkitError({
9971003
status: 'INVALID_ARGUMENT',
9981004
message: 'Action type is missing for ' + resolvedAction.__action.name,
9991005
});
10001006
}
1001-
registry.registerAction(resolvedAction.__action.actionType, resolvedAction);
1007+
registry.registerAction(
1008+
resolvedAction.__action.actionType,
1009+
resolvedAction,
1010+
{ namespace: plugin.name }
1011+
);
10021012
} else {
10031013
throw new GenkitError({
10041014
status: 'INVALID_ARGUMENT',

js/genkit/tests/plugins_test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,20 @@ const v2Plugin = genkitPluginV2({
7070
name: 'myV2Plugin',
7171
init() {
7272
return [
73-
model({ name: 'myV2Plugin/model_eager' }, async () => {
73+
model({ name: 'model_eager' }, async () => {
7474
return {};
7575
}),
7676
];
7777
},
7878
resolve(actionType, name) {
7979
switch (actionType) {
8080
case 'model':
81-
return model({ name: 'myV2Plugin/' + name }, async () => {
81+
return model({ name }, async () => {
8282
return {};
8383
});
8484
case 'background-model':
8585
return backgroundModel({
86-
name: 'myV2Plugin/' + name,
86+
name,
8787
async start() {
8888
return { id: 'abc' };
8989
},
@@ -100,10 +100,10 @@ const v2Plugin = genkitPluginV2({
100100
list() {
101101
return [
102102
modelActionMetadata({
103-
name: 'myV2Plugin/potential_model',
103+
name: 'potential_model',
104104
}),
105105
embedderActionMetadata({
106-
name: 'myV2Plugin/potential_embedder',
106+
name: 'potential_embedder',
107107
}),
108108
];
109109
},

0 commit comments

Comments
 (0)