mirror of
https://github.com/open-webui/open-webui
synced 2025-04-30 11:03:58 +00:00
refac: openapi to tool spec
This commit is contained in:
parent
332f8579d7
commit
463d7fb628
@ -374,60 +374,64 @@ def convert_openapi_to_tool_payload(openapi_spec):
|
|||||||
|
|
||||||
for path, methods in openapi_spec.get("paths", {}).items():
|
for path, methods in openapi_spec.get("paths", {}).items():
|
||||||
for method, operation in methods.items():
|
for method, operation in methods.items():
|
||||||
tool = {
|
if operation.get("operationId"):
|
||||||
"type": "function",
|
tool = {
|
||||||
"name": operation.get("operationId"),
|
"type": "function",
|
||||||
"description": operation.get(
|
"name": operation.get("operationId"),
|
||||||
"description", operation.get("summary", "No description available.")
|
"description": operation.get(
|
||||||
),
|
"description",
|
||||||
"parameters": {"type": "object", "properties": {}, "required": []},
|
operation.get("summary", "No description available."),
|
||||||
}
|
),
|
||||||
|
"parameters": {"type": "object", "properties": {}, "required": []},
|
||||||
# Extract path and query parameters
|
|
||||||
for param in operation.get("parameters", []):
|
|
||||||
param_name = param["name"]
|
|
||||||
param_schema = param.get("schema", {})
|
|
||||||
description = param_schema.get("description", "")
|
|
||||||
if not description:
|
|
||||||
description = param.get("description") or ""
|
|
||||||
if param_schema.get("enum") and isinstance(
|
|
||||||
param_schema.get("enum"), list
|
|
||||||
):
|
|
||||||
description += (
|
|
||||||
f". Possible values: {', '.join(param_schema.get('enum'))}"
|
|
||||||
)
|
|
||||||
tool["parameters"]["properties"][param_name] = {
|
|
||||||
"type": param_schema.get("type"),
|
|
||||||
"description": description,
|
|
||||||
}
|
}
|
||||||
if param.get("required"):
|
|
||||||
tool["parameters"]["required"].append(param_name)
|
|
||||||
|
|
||||||
# Extract and resolve requestBody if available
|
# Extract path and query parameters
|
||||||
request_body = operation.get("requestBody")
|
for param in operation.get("parameters", []):
|
||||||
if request_body:
|
param_name = param["name"]
|
||||||
content = request_body.get("content", {})
|
param_schema = param.get("schema", {})
|
||||||
json_schema = content.get("application/json", {}).get("schema")
|
description = param_schema.get("description", "")
|
||||||
if json_schema:
|
if not description:
|
||||||
resolved_schema = resolve_schema(
|
description = param.get("description") or ""
|
||||||
json_schema, openapi_spec.get("components", {})
|
if param_schema.get("enum") and isinstance(
|
||||||
)
|
param_schema.get("enum"), list
|
||||||
|
):
|
||||||
if resolved_schema.get("properties"):
|
description += (
|
||||||
tool["parameters"]["properties"].update(
|
f". Possible values: {', '.join(param_schema.get('enum'))}"
|
||||||
resolved_schema["properties"]
|
|
||||||
)
|
)
|
||||||
if "required" in resolved_schema:
|
tool["parameters"]["properties"][param_name] = {
|
||||||
tool["parameters"]["required"] = list(
|
"type": param_schema.get("type"),
|
||||||
set(
|
"description": description,
|
||||||
tool["parameters"]["required"]
|
}
|
||||||
+ resolved_schema["required"]
|
if param.get("required"):
|
||||||
)
|
tool["parameters"]["required"].append(param_name)
|
||||||
)
|
|
||||||
elif resolved_schema.get("type") == "array":
|
|
||||||
tool["parameters"] = resolved_schema # special case for array
|
|
||||||
|
|
||||||
tool_payload.append(tool)
|
# Extract and resolve requestBody if available
|
||||||
|
request_body = operation.get("requestBody")
|
||||||
|
if request_body:
|
||||||
|
content = request_body.get("content", {})
|
||||||
|
json_schema = content.get("application/json", {}).get("schema")
|
||||||
|
if json_schema:
|
||||||
|
resolved_schema = resolve_schema(
|
||||||
|
json_schema, openapi_spec.get("components", {})
|
||||||
|
)
|
||||||
|
|
||||||
|
if resolved_schema.get("properties"):
|
||||||
|
tool["parameters"]["properties"].update(
|
||||||
|
resolved_schema["properties"]
|
||||||
|
)
|
||||||
|
if "required" in resolved_schema:
|
||||||
|
tool["parameters"]["required"] = list(
|
||||||
|
set(
|
||||||
|
tool["parameters"]["required"]
|
||||||
|
+ resolved_schema["required"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif resolved_schema.get("type") == "array":
|
||||||
|
tool["parameters"] = (
|
||||||
|
resolved_schema # special case for array
|
||||||
|
)
|
||||||
|
|
||||||
|
tool_payload.append(tool)
|
||||||
|
|
||||||
return tool_payload
|
return tool_payload
|
||||||
|
|
||||||
|
@ -1243,60 +1243,62 @@ export const convertOpenApiToToolPayload = (openApiSpec) => {
|
|||||||
|
|
||||||
for (const [path, methods] of Object.entries(openApiSpec.paths)) {
|
for (const [path, methods] of Object.entries(openApiSpec.paths)) {
|
||||||
for (const [method, operation] of Object.entries(methods)) {
|
for (const [method, operation] of Object.entries(methods)) {
|
||||||
const tool = {
|
if (operation?.operationId) {
|
||||||
type: 'function',
|
const tool = {
|
||||||
name: operation.operationId,
|
type: 'function',
|
||||||
description: operation.description || operation.summary || 'No description available.',
|
name: operation.operationId,
|
||||||
parameters: {
|
description: operation.description || operation.summary || 'No description available.',
|
||||||
type: 'object',
|
parameters: {
|
||||||
properties: {},
|
type: 'object',
|
||||||
required: []
|
properties: {},
|
||||||
}
|
required: []
|
||||||
};
|
|
||||||
|
|
||||||
// Extract path and query parameters
|
|
||||||
if (operation.parameters) {
|
|
||||||
operation.parameters.forEach((param) => {
|
|
||||||
let description = param.schema.description || param.description || '';
|
|
||||||
if (param.schema.enum && Array.isArray(param.schema.enum)) {
|
|
||||||
description += `. Possible values: ${param.schema.enum.join(', ')}`;
|
|
||||||
}
|
}
|
||||||
tool.parameters.properties[param.name] = {
|
};
|
||||||
type: param.schema.type,
|
|
||||||
description: description
|
|
||||||
};
|
|
||||||
|
|
||||||
if (param.required) {
|
// Extract path and query parameters
|
||||||
tool.parameters.required.push(param.name);
|
if (operation.parameters) {
|
||||||
}
|
operation.parameters.forEach((param) => {
|
||||||
});
|
let description = param.schema.description || param.description || '';
|
||||||
}
|
if (param.schema.enum && Array.isArray(param.schema.enum)) {
|
||||||
|
description += `. Possible values: ${param.schema.enum.join(', ')}`;
|
||||||
// Extract and recursively resolve requestBody if available
|
}
|
||||||
if (operation.requestBody) {
|
tool.parameters.properties[param.name] = {
|
||||||
const content = operation.requestBody.content;
|
type: param.schema.type,
|
||||||
if (content && content['application/json']) {
|
description: description
|
||||||
const requestSchema = content['application/json'].schema;
|
|
||||||
const resolvedRequestSchema = resolveSchema(requestSchema, openApiSpec.components);
|
|
||||||
|
|
||||||
if (resolvedRequestSchema.properties) {
|
|
||||||
tool.parameters.properties = {
|
|
||||||
...tool.parameters.properties,
|
|
||||||
...resolvedRequestSchema.properties
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (resolvedRequestSchema.required) {
|
if (param.required) {
|
||||||
tool.parameters.required = [
|
tool.parameters.required.push(param.name);
|
||||||
...new Set([...tool.parameters.required, ...resolvedRequestSchema.required])
|
}
|
||||||
];
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract and recursively resolve requestBody if available
|
||||||
|
if (operation.requestBody) {
|
||||||
|
const content = operation.requestBody.content;
|
||||||
|
if (content && content['application/json']) {
|
||||||
|
const requestSchema = content['application/json'].schema;
|
||||||
|
const resolvedRequestSchema = resolveSchema(requestSchema, openApiSpec.components);
|
||||||
|
|
||||||
|
if (resolvedRequestSchema.properties) {
|
||||||
|
tool.parameters.properties = {
|
||||||
|
...tool.parameters.properties,
|
||||||
|
...resolvedRequestSchema.properties
|
||||||
|
};
|
||||||
|
|
||||||
|
if (resolvedRequestSchema.required) {
|
||||||
|
tool.parameters.required = [
|
||||||
|
...new Set([...tool.parameters.required, ...resolvedRequestSchema.required])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else if (resolvedRequestSchema.type === 'array') {
|
||||||
|
tool.parameters = resolvedRequestSchema; // special case when root schema is an array
|
||||||
}
|
}
|
||||||
} else if (resolvedRequestSchema.type === 'array') {
|
|
||||||
tool.parameters = resolvedRequestSchema; // special case when root schema is an array
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
toolPayload.push(tool);
|
toolPayload.push(tool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1304,15 +1306,17 @@ export const convertOpenApiToToolPayload = (openApiSpec) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const slugify = (str: string): string => {
|
export const slugify = (str: string): string => {
|
||||||
return str
|
return (
|
||||||
// 1. Normalize: separate accented letters into base + combining marks
|
str
|
||||||
.normalize("NFD")
|
// 1. Normalize: separate accented letters into base + combining marks
|
||||||
// 2. Remove all combining marks (the accents)
|
.normalize('NFD')
|
||||||
.replace(/[\u0300-\u036f]/g, "")
|
// 2. Remove all combining marks (the accents)
|
||||||
// 3. Replace any sequence of whitespace with a single hyphen
|
.replace(/[\u0300-\u036f]/g, '')
|
||||||
.replace(/\s+/g, "-")
|
// 3. Replace any sequence of whitespace with a single hyphen
|
||||||
// 4. Remove all characters except alphanumeric characters and hyphens
|
.replace(/\s+/g, '-')
|
||||||
.replace(/[^a-zA-Z0-9-]/g, "")
|
// 4. Remove all characters except alphanumeric characters and hyphens
|
||||||
// 5. Convert to lowercase
|
.replace(/[^a-zA-Z0-9-]/g, '')
|
||||||
.toLowerCase();
|
// 5. Convert to lowercase
|
||||||
|
.toLowerCase()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user