223 lines
7.6 KiB
Python
223 lines
7.6 KiB
Python
|
|
"""
|
|||
|
|
Tool Registry models for Mid Platform.
|
|||
|
|
[AC-IDMP-19] Tool Registry 治理模型
|
|||
|
|
|
|||
|
|
Reference: spec/intent-driven-mid-platform/openapi.provider.yaml
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import uuid
|
|||
|
|
from dataclasses import dataclass, field
|
|||
|
|
from datetime import datetime
|
|||
|
|
from enum import Enum
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
from sqlalchemy import JSON, Column
|
|||
|
|
from sqlmodel import Field, Index, SQLModel
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolStatus(str, Enum):
|
|||
|
|
"""工具状态"""
|
|||
|
|
ENABLED = "enabled"
|
|||
|
|
DISABLED = "disabled"
|
|||
|
|
DEPRECATED = "deprecated"
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolAuthType(str, Enum):
|
|||
|
|
"""工具鉴权类型"""
|
|||
|
|
NONE = "none"
|
|||
|
|
API_KEY = "api_key"
|
|||
|
|
OAUTH = "oauth"
|
|||
|
|
CUSTOM = "custom"
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class ToolAuthConfig:
|
|||
|
|
"""
|
|||
|
|
[AC-IDMP-19] 工具鉴权配置
|
|||
|
|
"""
|
|||
|
|
auth_type: ToolAuthType = ToolAuthType.NONE
|
|||
|
|
required_scopes: list[str] = field(default_factory=list)
|
|||
|
|
api_key_header: str | None = None
|
|||
|
|
oauth_url: str | None = None
|
|||
|
|
custom_validator: str | None = None
|
|||
|
|
|
|||
|
|
def to_dict(self) -> dict[str, Any]:
|
|||
|
|
result = {"auth_type": self.auth_type.value}
|
|||
|
|
if self.required_scopes:
|
|||
|
|
result["required_scopes"] = self.required_scopes
|
|||
|
|
if self.api_key_header:
|
|||
|
|
result["api_key_header"] = self.api_key_header
|
|||
|
|
if self.oauth_url:
|
|||
|
|
result["oauth_url"] = self.oauth_url
|
|||
|
|
if self.custom_validator:
|
|||
|
|
result["custom_validator"] = self.custom_validator
|
|||
|
|
return result
|
|||
|
|
|
|||
|
|
@classmethod
|
|||
|
|
def from_dict(cls, data: dict[str, Any]) -> "ToolAuthConfig":
|
|||
|
|
return cls(
|
|||
|
|
auth_type=ToolAuthType(data.get("auth_type", "none")),
|
|||
|
|
required_scopes=data.get("required_scopes", []),
|
|||
|
|
api_key_header=data.get("api_key_header"),
|
|||
|
|
oauth_url=data.get("oauth_url"),
|
|||
|
|
custom_validator=data.get("custom_validator"),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class ToolTimeoutPolicy:
|
|||
|
|
"""
|
|||
|
|
[AC-IDMP-19] 工具超时策略
|
|||
|
|
Reference: openapi.provider.yaml - TimeoutProfile
|
|||
|
|
"""
|
|||
|
|
per_tool_timeout_ms: int = 30000
|
|||
|
|
end_to_end_timeout_ms: int = 120000
|
|||
|
|
retry_count: int = 0
|
|||
|
|
retry_delay_ms: int = 100
|
|||
|
|
|
|||
|
|
def to_dict(self) -> dict[str, Any]:
|
|||
|
|
return {
|
|||
|
|
"per_tool_timeout_ms": self.per_tool_timeout_ms,
|
|||
|
|
"end_to_end_timeout_ms": self.end_to_end_timeout_ms,
|
|||
|
|
"retry_count": self.retry_count,
|
|||
|
|
"retry_delay_ms": self.retry_delay_ms,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@classmethod
|
|||
|
|
def from_dict(cls, data: dict[str, Any]) -> "ToolTimeoutPolicy":
|
|||
|
|
return cls(
|
|||
|
|
per_tool_timeout_ms=data.get("per_tool_timeout_ms", 30000),
|
|||
|
|
end_to_end_timeout_ms=data.get("end_to_end_timeout_ms", 120000),
|
|||
|
|
retry_count=data.get("retry_count", 0),
|
|||
|
|
retry_delay_ms=data.get("retry_delay_ms", 100),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class ToolDefinition:
|
|||
|
|
"""
|
|||
|
|
[AC-IDMP-19] 工具定义(内存模型)
|
|||
|
|
|
|||
|
|
包含:
|
|||
|
|
- name: 工具名称
|
|||
|
|
- type: 工具类型 (internal | mcp)
|
|||
|
|
- version: 版本号
|
|||
|
|
- timeout_policy: 超时策略
|
|||
|
|
- auth_config: 鉴权配置
|
|||
|
|
- is_enabled: 启停状态
|
|||
|
|
"""
|
|||
|
|
name: str
|
|||
|
|
type: str = "internal"
|
|||
|
|
version: str = "1.0.0"
|
|||
|
|
description: str | None = None
|
|||
|
|
timeout_policy: ToolTimeoutPolicy = field(default_factory=ToolTimeoutPolicy)
|
|||
|
|
auth_config: ToolAuthConfig = field(default_factory=ToolAuthConfig)
|
|||
|
|
is_enabled: bool = True
|
|||
|
|
metadata: dict[str, Any] = field(default_factory=dict)
|
|||
|
|
created_at: datetime = field(default_factory=datetime.utcnow)
|
|||
|
|
updated_at: datetime = field(default_factory=datetime.utcnow)
|
|||
|
|
|
|||
|
|
def to_dict(self) -> dict[str, Any]:
|
|||
|
|
return {
|
|||
|
|
"name": self.name,
|
|||
|
|
"type": self.type,
|
|||
|
|
"version": self.version,
|
|||
|
|
"description": self.description,
|
|||
|
|
"timeout_policy": self.timeout_policy.to_dict(),
|
|||
|
|
"auth_config": self.auth_config.to_dict(),
|
|||
|
|
"is_enabled": self.is_enabled,
|
|||
|
|
"metadata": self.metadata,
|
|||
|
|
"created_at": self.created_at.isoformat(),
|
|||
|
|
"updated_at": self.updated_at.isoformat(),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@classmethod
|
|||
|
|
def from_dict(cls, data: dict[str, Any]) -> "ToolDefinition":
|
|||
|
|
return cls(
|
|||
|
|
name=data["name"],
|
|||
|
|
type=data.get("type", "internal"),
|
|||
|
|
version=data.get("version", "1.0.0"),
|
|||
|
|
description=data.get("description"),
|
|||
|
|
timeout_policy=ToolTimeoutPolicy.from_dict(data.get("timeout_policy", {})),
|
|||
|
|
auth_config=ToolAuthConfig.from_dict(data.get("auth_config", {})),
|
|||
|
|
is_enabled=data.get("is_enabled", True),
|
|||
|
|
metadata=data.get("metadata", {}),
|
|||
|
|
created_at=datetime.fromisoformat(data["created_at"]) if data.get("created_at") else datetime.utcnow(),
|
|||
|
|
updated_at=datetime.fromisoformat(data["updated_at"]) if data.get("updated_at") else datetime.utcnow(),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolRegistryEntity(SQLModel, table=True):
|
|||
|
|
"""
|
|||
|
|
[AC-IDMP-19] 工具注册表数据库实体
|
|||
|
|
支持动态配置更新
|
|||
|
|
"""
|
|||
|
|
__tablename__ = "tool_registry"
|
|||
|
|
__table_args__ = (
|
|||
|
|
Index("ix_tool_registry_tenant_name", "tenant_id", "name", unique=True),
|
|||
|
|
Index("ix_tool_registry_tenant_enabled", "tenant_id", "is_enabled"),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
|
|||
|
|
tenant_id: str = Field(..., description="租户ID", index=True)
|
|||
|
|
name: str = Field(..., description="工具名称", max_length=128)
|
|||
|
|
type: str = Field(default="internal", description="工具类型: internal | mcp")
|
|||
|
|
version: str = Field(default="1.0.0", description="版本号", max_length=32)
|
|||
|
|
description: str | None = Field(default=None, description="工具描述")
|
|||
|
|
timeout_policy: dict[str, Any] | None = Field(
|
|||
|
|
default=None,
|
|||
|
|
sa_column=Column("timeout_policy", JSON, nullable=True),
|
|||
|
|
description="超时策略配置"
|
|||
|
|
)
|
|||
|
|
auth_config: dict[str, Any] | None = Field(
|
|||
|
|
default=None,
|
|||
|
|
sa_column=Column("auth_config", JSON, nullable=True),
|
|||
|
|
description="鉴权配置"
|
|||
|
|
)
|
|||
|
|
is_enabled: bool = Field(default=True, description="是否启用")
|
|||
|
|
metadata_: dict[str, Any] | None = Field(
|
|||
|
|
default=None,
|
|||
|
|
sa_column=Column("metadata", JSON, nullable=True),
|
|||
|
|
description="扩展元数据"
|
|||
|
|
)
|
|||
|
|
created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
|
|||
|
|
updated_at: datetime = Field(default_factory=datetime.utcnow, description="更新时间")
|
|||
|
|
|
|||
|
|
def to_definition(self) -> ToolDefinition:
|
|||
|
|
"""转换为内存模型"""
|
|||
|
|
return ToolDefinition(
|
|||
|
|
name=self.name,
|
|||
|
|
type=self.type,
|
|||
|
|
version=self.version,
|
|||
|
|
description=self.description,
|
|||
|
|
timeout_policy=ToolTimeoutPolicy.from_dict(self.timeout_policy or {}),
|
|||
|
|
auth_config=ToolAuthConfig.from_dict(self.auth_config or {}),
|
|||
|
|
is_enabled=self.is_enabled,
|
|||
|
|
metadata=self.metadata_ or {},
|
|||
|
|
created_at=self.created_at,
|
|||
|
|
updated_at=self.updated_at,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolRegistryCreate(SQLModel):
|
|||
|
|
"""创建工具注册请求"""
|
|||
|
|
name: str = Field(..., max_length=128)
|
|||
|
|
type: str = "internal"
|
|||
|
|
version: str = "1.0.0"
|
|||
|
|
description: str | None = None
|
|||
|
|
timeout_policy: dict[str, Any] | None = None
|
|||
|
|
auth_config: dict[str, Any] | None = None
|
|||
|
|
is_enabled: bool = True
|
|||
|
|
metadata_: dict[str, Any] | None = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class ToolRegistryUpdate(SQLModel):
|
|||
|
|
"""更新工具注册请求"""
|
|||
|
|
type: str | None = None
|
|||
|
|
version: str | None = None
|
|||
|
|
description: str | None = None
|
|||
|
|
timeout_policy: dict[str, Any] | None = None
|
|||
|
|
auth_config: dict[str, Any] | None = None
|
|||
|
|
is_enabled: bool | None = None
|
|||
|
|
metadata_: dict[str, Any] | None = None
|