feat: init commint
This commit is contained in:
@@ -5,6 +5,10 @@ from typing import Any
|
||||
|
||||
from jsonschema import Draft202012Validator, ValidationError
|
||||
|
||||
from apps.modelhub.structured_output import (
|
||||
StructuredOutputError,
|
||||
validate_native_schema_subset,
|
||||
)
|
||||
from apps.skills.models import SkillDefinition, SkillVersion
|
||||
|
||||
VARIABLE_PATTERN = re.compile(r"{{\s*([^{}]+?)\s*}}")
|
||||
@@ -32,10 +36,48 @@ def validate_prompt_template(template: str) -> None:
|
||||
raise SkillValidationError(f"不允许的模板变量: {variable.strip()}")
|
||||
|
||||
|
||||
def _validate_output_object_shapes(schema: dict[str, Any], path: str = "$") -> None:
|
||||
schema_type = schema.get("type")
|
||||
if schema_type == "object":
|
||||
properties = schema.get("properties")
|
||||
if not isinstance(properties, dict):
|
||||
raise SkillValidationError(f"输出 Schema 对象必须声明 properties: {path}")
|
||||
if schema.get("additionalProperties") is not False:
|
||||
raise SkillValidationError(
|
||||
f"输出 Schema 对象必须设置 additionalProperties=false: {path}"
|
||||
)
|
||||
required = schema.get("required")
|
||||
if not isinstance(required, list) or set(required) != set(properties):
|
||||
raise SkillValidationError(
|
||||
f"输出 Schema 对象的全部字段都必须列入 required: {path}"
|
||||
)
|
||||
for code, child in properties.items():
|
||||
if isinstance(child, dict):
|
||||
_validate_output_object_shapes(child, f"{path}.{code}")
|
||||
elif schema_type == "array":
|
||||
items = schema.get("items")
|
||||
if isinstance(items, dict):
|
||||
_validate_output_object_shapes(items, f"{path}[]")
|
||||
|
||||
|
||||
def validate_skill_version(version: SkillVersion) -> None:
|
||||
validate_prompt_template(version.prompt_template)
|
||||
validate_json_schema(version.input_schema, "输入 Schema")
|
||||
validate_json_schema(version.output_schema, "输出 Schema")
|
||||
if version.output_schema.get("type") != "object":
|
||||
raise SkillValidationError("输出 Schema 根节点必须是 object")
|
||||
if version.output_enforcement not in {
|
||||
"native_json_schema",
|
||||
"json_object",
|
||||
"validated_json",
|
||||
}:
|
||||
raise SkillValidationError("未知的结构化输出保障要求")
|
||||
_validate_output_object_shapes(version.output_schema)
|
||||
if version.output_enforcement == "native_json_schema":
|
||||
try:
|
||||
validate_native_schema_subset(version.output_schema)
|
||||
except StructuredOutputError as error:
|
||||
raise SkillValidationError(str(error)) from error
|
||||
if version.example_input:
|
||||
try:
|
||||
Draft202012Validator(version.input_schema).validate(version.example_input)
|
||||
@@ -91,6 +133,7 @@ def ensure_draft(definition: SkillDefinition, user=None) -> SkillVersion:
|
||||
prompt_template=source.prompt_template if source else "",
|
||||
input_schema=deepcopy(source.input_schema) if source else {"type": "object"},
|
||||
output_schema=deepcopy(source.output_schema) if source else {"type": "object"},
|
||||
output_enforcement=source.output_enforcement if source else "validated_json",
|
||||
example_input=deepcopy(source.example_input) if source else {},
|
||||
created_by=user,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user