This commit is contained in:
No BS AI 2026-10-27 02:25:20 +00:00 • committed by GitHub
commit d72871188a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 4 deletions

View file

@ -167,6 +167,25 @@ describe("key ownership", () => {
});
});
describe("tags", () => {
it("stores the Tags field inside metadata and leaves it off the top level", () => {
const values = {
key_alias: "my-key",
metadata: '{"team":"core","tags":["from-json"]}',
tags: ["production", "pilot"],
};
const before = structuredClone(values);
const payload = payloadOf(build(values));
expect(values).toStrictEqual(before);
expect(payload).not.toHaveProperty("tags");
expect(JSON.parse(String(payload.metadata))).toEqual({
team: "core",
tags: ["production", "pilot"],
});
});
});
describe("metadata", () => {
it("re-serialises the parsed form value", () => {
expect(payloadOf(build({ key_alias: "my-key", metadata: '{"team":"core"}' }))).toStrictEqual(

View file

@ -90,6 +90,17 @@ const parseMetadata = (raw: unknown): unknown => {
}
};
const selectedTags = (raw: unknown): unknown[] | undefined => (Array.isArray(raw) && raw.length > 0 ? raw : undefined);
const metadataWithSelectedTags = (parsed: unknown, rawTags: unknown): unknown => {
const tags = selectedTags(rawTags);
if (!tags) return parsed;
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
return { ...parsed, tags };
}
return { tags };
};
const buildMetadataJson = (values: Record<string, unknown>, input: KeyCreateInput): string => {
const parsed = parseMetadata(values.metadata);
if (input.keyOwner === "service_account") {
@ -103,7 +114,7 @@ const buildMetadataJson = (values: Record<string, unknown>, input: KeyCreateInpu
input.disabledCallbacks.length > 0
? { ...(logged as object), litellm_disabled_callbacks: mapDisplayToInternalNames(input.disabledCallbacks) }
: logged;
return JSON.stringify(disabled);
return JSON.stringify(metadataWithSelectedTags(disabled, values.tags));
};
interface PermissionSources {
@ -183,7 +194,10 @@ export const buildKeyCreatePayload = (input: KeyCreateInput): KeyPayloadResult =
const sources = readPermissionSources(values);
const objectPermission = buildObjectPermission(sources);
const dropped = consumedSourceKeys(values, sources);
const dropped = new Set<string>([
...consumedSourceKeys(values, sources),
...(selectedTags(values.tags) ? ["tags"] : []),
]);
const duration = values.duration;
const validWindows = input.budgetLimits.filter(

View file

@ -473,7 +473,7 @@ describe("CreateKey", () => {
expect(payload.budget_duration).toBeNull();
});
it("routes typed tags into the tags key", async () => {
it("routes typed tags into metadata, the same place key edit sends them", async () => {
state.tags = { production: { name: "production" } };
await openModal();
await nameTheKey();
@ -481,7 +481,9 @@ describe("CreateKey", () => {
await userEvent.type(await screen.findByLabelText("Tags"), "production{Enter}");
await submit();
expect((await createdPayload()).tags).toStrictEqual(["production"]);
const payload = await createdPayload();
expect(payload).not.toHaveProperty("tags");
expect(JSON.parse(String(payload.metadata))).toMatchObject({ tags: ["production"] });
});
it("routes a chosen access group into access_group_ids", async () => {