From c18a9b7776e9c85adf53c876297ff5cc70e550bb Mon Sep 17 00:00:00 2001 From: John Huang Date: Wed, 27 May 2026 18:53:06 -0700 Subject: [PATCH] parameters tags --- js/src/framework.test.ts | 77 ++++++++++++++++++++++++++++++++++++++++ js/src/framework2.ts | 6 ++++ 2 files changed, 83 insertions(+) diff --git a/js/src/framework.test.ts b/js/src/framework.test.ts index 4e6a83d01..c91d571cc 100644 --- a/js/src/framework.test.ts +++ b/js/src/framework.test.ts @@ -1283,6 +1283,83 @@ describe("framework2 metadata support", () => { }); }); + describe("CodeParameters tags", () => { + test("parameters stores tags correctly", () => { + const project = projects.create({ name: "test-project" }); + const tags = ["ci", "production"]; + + project.parameters.create({ + name: "test-parameters", + schema: { + model: { + type: "model", + default: "gpt-5-mini", + }, + }, + tags, + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const parameters = (project as any)._publishableParameters; + expect(parameters).toHaveLength(1); + expect(parameters[0].tags).toEqual(tags); + }); + + test("toFunctionDefinition includes tags when present", async () => { + const project = projects.create({ name: "test-project" }); + const tags = ["ci", "production"]; + + project.parameters.create({ + name: "test-parameters", + schema: { + model: { + type: "model", + default: "gpt-5-mini", + }, + }, + tags, + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const parameters = (project as any)._publishableParameters; + const mockProjectMap = { + resolve: vi.fn().mockResolvedValue("project-123"), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + const funcDef = await parameters[0].toFunctionDefinition(mockProjectMap); + + expect(funcDef.tags).toEqual(tags); + expect(funcDef.name).toBe("test-parameters"); + expect(funcDef.project_id).toBe("project-123"); + }); + + test("toFunctionDefinition excludes tags when undefined", async () => { + const project = projects.create({ name: "test-project" }); + + project.parameters.create({ + name: "test-parameters", + schema: { + model: { + type: "model", + default: "gpt-5-mini", + }, + }, + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const parameters = (project as any)._publishableParameters; + const mockProjectMap = { + resolve: vi.fn().mockResolvedValue("project-123"), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any; + + const funcDef = await parameters[0].toFunctionDefinition(mockProjectMap); + + expect(funcDef.tags).toBeUndefined(); + }); + }); + describe("CodeParameters defaults", () => { test("toFunctionDefinition initializes data with schema defaults", async () => { const project = projects.create({ name: "test-project" }); diff --git a/js/src/framework2.ts b/js/src/framework2.ts index 4ec3bf5ab..8812eb3eb 100644 --- a/js/src/framework2.ts +++ b/js/src/framework2.ts @@ -586,6 +586,7 @@ export interface ParametersOpts { description?: string; schema: S; ifExists?: IfExists; + tags?: string[]; metadata?: Record; } @@ -596,6 +597,7 @@ export class CodeParameters { public readonly description?: string; public readonly schema: EvalParameters; public readonly ifExists?: IfExists; + public readonly tags?: string[]; public readonly metadata?: Record; constructor( @@ -606,6 +608,7 @@ export class CodeParameters { description?: string; schema: EvalParameters; ifExists?: IfExists; + tags?: string[]; metadata?: Record; }, ) { @@ -615,6 +618,7 @@ export class CodeParameters { this.description = opts.description; this.schema = opts.schema; this.ifExists = opts.ifExists; + this.tags = opts.tags; this.metadata = opts.metadata; } @@ -634,6 +638,7 @@ export class CodeParameters { __schema: schema, }, if_exists: this.ifExists, + tags: this.tags, metadata: this.metadata, }; } @@ -651,6 +656,7 @@ class ParametersBuilder { description: opts.description, schema: opts.schema, ifExists: opts.ifExists, + tags: opts.tags, metadata: opts.metadata, });