mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-30 01:52:18 +00:00
chore(mcp): regenerate openapi artifacts and sync payload expectations
Co-Authored-By: bot_apk <apk@cognition.ai>
This commit is contained in:
parent
e7456e8a0f
commit
4dd482e923
11 changed files with 104 additions and 28 deletions
|
|
@ -2856,6 +2856,20 @@
|
|||
],
|
||||
"title": "Mcp Servers"
|
||||
},
|
||||
"mcp_tool_overrides": {
|
||||
"anyOf": [
|
||||
{
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/MCPToolOverrideEntry"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Mcp Tool Overrides"
|
||||
},
|
||||
"mcp_tool_permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
@ -3574,6 +3588,27 @@
|
|||
"title": "KeyMetricWithMetadata",
|
||||
"type": "object"
|
||||
},
|
||||
"MCPToolOverrideEntry": {
|
||||
"description": "Per-server tool overrides stored on an object permission row's\n``mcp_tool_overrides``: ``allow`` re-arms names the convention denies,\n``deny`` disables names the convention or an allowlist would permit.",
|
||||
"properties": {
|
||||
"allow": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "Allow",
|
||||
"type": "array"
|
||||
},
|
||||
"deny": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": "Deny",
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"title": "MCPToolOverrideEntry",
|
||||
"type": "object"
|
||||
},
|
||||
"MakeAgentsPublicRequest": {
|
||||
"properties": {
|
||||
"agent_ids": {
|
||||
|
|
|
|||
|
|
@ -817,6 +817,9 @@ _EXPECTED_CUSTOMER = {
|
|||
"mcp_servers": ["s1"],
|
||||
"mcp_access_groups": [],
|
||||
"mcp_tool_permissions": None,
|
||||
"mcp_tool_overrides": None,
|
||||
"mcp_tool_permissions_archive": None,
|
||||
"mcp_permission_version": None,
|
||||
"vector_stores": [],
|
||||
"agents": [],
|
||||
"agent_access_groups": [],
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ describe("AgentInfoView update payload", () => {
|
|||
rpm_limit: 222,
|
||||
session_tpm_limit: 333,
|
||||
session_rpm_limit: 444,
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {} },
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {}, mcp_tool_overrides: {} },
|
||||
access_group_ids: [],
|
||||
});
|
||||
});
|
||||
|
|
@ -221,7 +221,7 @@ describe("AgentInfoView update payload", () => {
|
|||
rpm_limit: 222,
|
||||
session_tpm_limit: 333,
|
||||
session_rpm_limit: 444,
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {} },
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {}, mcp_tool_overrides: {} },
|
||||
access_group_ids: [],
|
||||
});
|
||||
});
|
||||
|
|
@ -300,7 +300,7 @@ describe("AgentInfoView update payload", () => {
|
|||
api_base: "https://other.example.com",
|
||||
model: "langgraph/asst_1",
|
||||
},
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {} },
|
||||
object_permission: { mcp_servers: [], mcp_access_groups: [], mcp_toolsets: [], mcp_tool_permissions: {}, mcp_tool_overrides: {} },
|
||||
access_group_ids: [],
|
||||
});
|
||||
});
|
||||
|
|
@ -311,6 +311,7 @@ describe("AgentInfoView update payload", () => {
|
|||
mcp_access_groups: ["grp-a"],
|
||||
mcp_toolsets: ["toolset-1"],
|
||||
mcp_tool_permissions: { "srv-1": ["tool_x"] },
|
||||
mcp_tool_overrides: {},
|
||||
};
|
||||
vi.mocked(networking.getAgentInfo).mockResolvedValue({
|
||||
...A2A_AGENT,
|
||||
|
|
|
|||
|
|
@ -103,7 +103,9 @@ const teamCreateFieldsSchema = z.object({
|
|||
})
|
||||
.optional(),
|
||||
mcp_tool_permissions: z.record(z.string(), z.array(z.string())).optional(),
|
||||
mcp_tool_overrides: z.record(z.string(), z.object({ allow: z.array(z.string()), deny: z.array(z.string()) })).optional(),
|
||||
mcp_tool_overrides: z
|
||||
.record(z.string(), z.object({ allow: z.array(z.string()), deny: z.array(z.string()) }))
|
||||
.optional(),
|
||||
allowed_agents_and_groups: z.object({ agents: z.array(z.string()), accessGroups: z.array(z.string()) }).optional(),
|
||||
object_permission_search_tools: z.array(z.string()).optional(),
|
||||
object_permission_skills: z.array(z.string()).optional(),
|
||||
|
|
|
|||
|
|
@ -350,7 +350,8 @@ const MCPToolPermissions: React.FC<MCPToolPermissionsProps> = ({
|
|||
permissionKey: entry.permissionKey,
|
||||
edits: tools
|
||||
.filter(
|
||||
(tool) => allowed.includes(tool.name) !== stateFor(tool).checked && !stateFor(tool).locked,
|
||||
(tool) =>
|
||||
allowed.includes(tool.name) !== stateFor(tool).checked && !stateFor(tool).locked,
|
||||
)
|
||||
.map((tool) => ({
|
||||
toolName: tool.name,
|
||||
|
|
|
|||
|
|
@ -612,7 +612,11 @@ describe("convention servers and tool overrides", () => {
|
|||
});
|
||||
|
||||
it("locks toolset tools as granted", () => {
|
||||
const toolset = { toolset_id: "ts-1", toolset_name: "TS", tools: [{ server_id: "srv-1", tool_name: "list_pages" }] };
|
||||
const toolset = {
|
||||
toolset_id: "ts-1",
|
||||
toolset_name: "TS",
|
||||
tools: [{ server_id: "srv-1", tool_name: "list_pages" }],
|
||||
};
|
||||
const input: Parameters<typeof resolveEffectiveMcpServers>[0] = {
|
||||
...emptyInput,
|
||||
allServers: [srv],
|
||||
|
|
@ -640,7 +644,13 @@ describe("convention servers and tool overrides", () => {
|
|||
it("moves a delete tool in and out of allow on toggle", () => {
|
||||
const overrides = { "srv-1": { allow: [], deny: ["list_pages"] } };
|
||||
|
||||
const grant = { toolOverrides: overrides, permissionKey: "srv-1", toolName: "delete_page", isDeleteTool: true, checked: true };
|
||||
const grant = {
|
||||
toolOverrides: overrides,
|
||||
permissionKey: "srv-1",
|
||||
toolName: "delete_page",
|
||||
isDeleteTool: true,
|
||||
checked: true,
|
||||
};
|
||||
|
||||
expect(applyToolOverrideWrite(grant)).toEqual({ "srv-1": { allow: ["delete_page"], deny: ["list_pages"] } });
|
||||
|
||||
|
|
@ -656,7 +666,13 @@ describe("convention servers and tool overrides", () => {
|
|||
});
|
||||
|
||||
it("moves a non-delete tool in and out of deny on toggle without writing allows", () => {
|
||||
const deny = { toolOverrides: {}, permissionKey: "srv-1", toolName: "list_pages", isDeleteTool: false, checked: false };
|
||||
const deny = {
|
||||
toolOverrides: {},
|
||||
permissionKey: "srv-1",
|
||||
toolName: "list_pages",
|
||||
isDeleteTool: false,
|
||||
checked: false,
|
||||
};
|
||||
|
||||
expect(applyToolOverrideWrite(deny)).toEqual({ "srv-1": { allow: [], deny: ["list_pages"] } });
|
||||
|
||||
|
|
@ -731,14 +747,14 @@ describe("retainedMcpToolOverrides", () => {
|
|||
});
|
||||
|
||||
it("keeps an override while any server the key names stays granted", () => {
|
||||
expect(
|
||||
retainedMcpToolOverrides({ shared: { allow: [], deny: ["t"] } }, new Set(["srv-2"]), catalog),
|
||||
).toEqual({ shared: { allow: [], deny: ["t"] } });
|
||||
expect(retainedMcpToolOverrides({ shared: { allow: [], deny: ["t"] } }, new Set(["srv-2"]), catalog)).toEqual({
|
||||
shared: { allow: [], deny: ["t"] },
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps an override whose key resolves to nothing, so an unloaded catalog prunes nothing", () => {
|
||||
expect(retainedMcpToolOverrides({ "not-yet-loaded": { allow: [], deny: ["t"] } }, new Set(), catalog)).toEqual(
|
||||
{ "not-yet-loaded": { allow: [], deny: ["t"] } },
|
||||
);
|
||||
expect(retainedMcpToolOverrides({ "not-yet-loaded": { allow: [], deny: ["t"] } }, new Set(), catalog)).toEqual({
|
||||
"not-yet-loaded": { allow: [], deny: ["t"] },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -265,11 +265,7 @@ export const resolveEffectiveMcpServers = ({
|
|||
);
|
||||
};
|
||||
|
||||
export const mcpToolState = (
|
||||
entry: EffectiveMcpServer,
|
||||
toolName: string,
|
||||
isDeleteTool: boolean,
|
||||
): McpToolState => {
|
||||
export const mcpToolState = (entry: EffectiveMcpServer, toolName: string, isDeleteTool: boolean): McpToolState => {
|
||||
const denied = (entry.overrides?.deny ?? []).includes(toolName);
|
||||
if (denied) {
|
||||
if (entry.keyedTools !== undefined) {
|
||||
|
|
@ -335,7 +331,16 @@ export const applyToolOverrideWrites = ({
|
|||
readonly permissionKey: string;
|
||||
readonly edits: readonly { toolName: string; isDeleteTool: boolean; checked: boolean }[];
|
||||
}): Record<string, McpToolOverrideEntry> =>
|
||||
edits.reduce((overrides, edit) => {
|
||||
const write = { toolOverrides: overrides, permissionKey, toolName: edit.toolName, isDeleteTool: edit.isDeleteTool, checked: edit.checked };
|
||||
return applyToolOverrideWrite(write);
|
||||
}, { ...toolOverrides });
|
||||
edits.reduce(
|
||||
(overrides, edit) => {
|
||||
const write = {
|
||||
toolOverrides: overrides,
|
||||
permissionKey,
|
||||
toolName: edit.toolName,
|
||||
isDeleteTool: edit.isDeleteTool,
|
||||
checked: edit.checked,
|
||||
};
|
||||
return applyToolOverrideWrite(write);
|
||||
},
|
||||
{ ...toolOverrides },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -404,7 +404,9 @@ const teamUpdateFieldsSchema = z.object({
|
|||
})
|
||||
.optional(),
|
||||
mcp_tool_permissions: z.record(z.string(), z.array(z.string())).optional(),
|
||||
mcp_tool_overrides: z.record(z.string(), z.object({ allow: z.array(z.string()), deny: z.array(z.string()) })).optional(),
|
||||
mcp_tool_overrides: z
|
||||
.record(z.string(), z.object({ allow: z.array(z.string()), deny: z.array(z.string()) }))
|
||||
.optional(),
|
||||
agents_and_groups: z.object({ agents: z.array(z.string()), accessGroups: z.array(z.string()) }).optional(),
|
||||
object_permission_search_tools: z.array(z.string()).optional(),
|
||||
object_permission_skills: z.array(z.string()).optional(),
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ describe("KeyEditView", () => {
|
|||
mcp_servers: [],
|
||||
mcp_access_groups: [],
|
||||
mcp_tool_permissions: {},
|
||||
mcp_tool_overrides: {},
|
||||
vector_stores: [],
|
||||
},
|
||||
auto_rotate: false,
|
||||
|
|
@ -2112,6 +2113,7 @@ describe("KeyEditView", () => {
|
|||
vector_stores: [],
|
||||
mcp_servers_and_groups: { servers: [], accessGroups: [], toolsets: [] },
|
||||
mcp_tool_permissions: {},
|
||||
mcp_tool_overrides: {},
|
||||
agents_and_groups: { agents: [], accessGroups: [] },
|
||||
skills: [],
|
||||
organization_id: null,
|
||||
|
|
|
|||
4
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
4
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
|
|
@ -24417,6 +24417,10 @@ export interface components {
|
|||
mcp_access_groups?: string[] | null;
|
||||
/** Mcp Servers */
|
||||
mcp_servers?: string[] | null;
|
||||
/** Mcp Tool Overrides */
|
||||
mcp_tool_overrides?: {
|
||||
[key: string]: components["schemas"]["MCPToolOverrideEntry"];
|
||||
} | null;
|
||||
/** Mcp Tool Permissions */
|
||||
mcp_tool_permissions?: {
|
||||
[key: string]: string[];
|
||||
|
|
|
|||
|
|
@ -91,12 +91,17 @@ const descriptionTokens = (description: string): string[] =>
|
|||
.filter((token) => token.length > 0)
|
||||
.map((token) => token.toLowerCase());
|
||||
|
||||
const stripSuffix = (token: string, suffix: string): string => (token.endsWith(suffix) ? token.slice(0, -suffix.length) : token);
|
||||
const stripSuffix = (token: string, suffix: string): string =>
|
||||
token.endsWith(suffix) ? token.slice(0, -suffix.length) : token;
|
||||
|
||||
const tokenVariants = (token: string): string[] =>
|
||||
[token, stripSuffix(token, "es"), stripSuffix(token, "s"), stripSuffix(token, "ed"), stripSuffix(token, "ing")].filter(
|
||||
(variant) => variant.length > 0,
|
||||
);
|
||||
[
|
||||
token,
|
||||
stripSuffix(token, "es"),
|
||||
stripSuffix(token, "s"),
|
||||
stripSuffix(token, "ed"),
|
||||
stripSuffix(token, "ing"),
|
||||
].filter((variant) => variant.length > 0);
|
||||
|
||||
const CONJUNCTION_TOKENS = new Set(["and", "then", "or", "n"]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue