chore: auto release commit (2026-06-19 09:53:29)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
All checks were successful
技能自动化发布 / release (push) Successful in 7s
This commit is contained in:
@@ -6,11 +6,17 @@ Central authoritative registry for all platforms (logistics, LLM, content, etc.)
|
||||
Import and use PLATFORMS dict, resolve_platform_key(), and seed_platforms().
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional
|
||||
|
||||
from util.logging_config import get_skill_logger
|
||||
|
||||
PLATFORM_KEY_PATTERN = re.compile(r"^[a-z0-9][a-z0-9_-]{1,63}$")
|
||||
|
||||
DEFAULT_CAPABILITIES_JSON = '{"web": true, "api_key": false, "rpa": true}'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Platform specification fields:
|
||||
# display_name – Human-readable name (e.g. "Maersk")
|
||||
@@ -309,7 +315,7 @@ _PLATFORM_ALIAS_MAP = _build_alias_map()
|
||||
|
||||
def resolve_platform_key(name: str) -> Optional[str]:
|
||||
"""
|
||||
Resolve user input to a canonical platform key.
|
||||
Resolve user input to a canonical platform key (built-in PLATFORMS only).
|
||||
Supports: key, display_name, any alias. Case-insensitive.
|
||||
Returns None if unrecognized.
|
||||
"""
|
||||
@@ -330,8 +336,154 @@ def resolve_platform_key(name: str) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def is_valid_platform_key_format(name: str) -> bool:
|
||||
"""平台 key 格式:^[a-z0-9][a-z0-9_-]{1,63}$"""
|
||||
s = (name or "").strip().lower()
|
||||
if not s:
|
||||
return False
|
||||
return bool(PLATFORM_KEY_PATTERN.match(s))
|
||||
|
||||
|
||||
def _parse_aliases_json(val: Any) -> list[str]:
|
||||
if val is None:
|
||||
return []
|
||||
try:
|
||||
data = json.loads(val) if isinstance(val, str) else val
|
||||
if isinstance(data, list):
|
||||
return [str(a).strip() for a in data if str(a).strip()]
|
||||
except (json.JSONDecodeError, TypeError, ValueError):
|
||||
pass
|
||||
return []
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PlatformResolveResult:
|
||||
platform_key: Optional[str] = None
|
||||
error_code: Optional[str] = None
|
||||
message: Optional[str] = None
|
||||
|
||||
@property
|
||||
def ok(self) -> bool:
|
||||
return bool(self.platform_key) and not self.error_code
|
||||
|
||||
|
||||
def _resolve_platform_from_db(conn, raw: str) -> PlatformResolveResult:
|
||||
"""在 platforms 表中解析:精确 key(enabled=1)与 aliases_json。"""
|
||||
raw_stripped = (raw or "").strip()
|
||||
raw_lower = raw_stripped.lower()
|
||||
|
||||
if is_valid_platform_key_format(raw_stripped):
|
||||
row = conn.execute(
|
||||
"SELECT platform_key, enabled FROM platforms WHERE platform_key = ?",
|
||||
(raw_lower,),
|
||||
).fetchone()
|
||||
if row:
|
||||
if not row[1]:
|
||||
return PlatformResolveResult(
|
||||
error_code="PLATFORM_DISABLED",
|
||||
message=f"平台 {row[0]} 已禁用。",
|
||||
)
|
||||
return PlatformResolveResult(platform_key=row[0])
|
||||
|
||||
rows = conn.execute(
|
||||
"SELECT platform_key, enabled, aliases_json FROM platforms"
|
||||
).fetchall()
|
||||
for platform_key, enabled, aliases_json in rows:
|
||||
if not enabled:
|
||||
continue
|
||||
names = {platform_key.lower()}
|
||||
for alias in _parse_aliases_json(aliases_json):
|
||||
names.add(alias.lower())
|
||||
names.add(alias)
|
||||
if raw_lower in names or raw_stripped in names:
|
||||
return PlatformResolveResult(platform_key=platform_key)
|
||||
|
||||
return PlatformResolveResult()
|
||||
|
||||
|
||||
def resolve_platform_key_dynamic(input_name: str, conn=None) -> PlatformResolveResult:
|
||||
"""
|
||||
统一平台解析:内置 PLATFORMS → DB platforms 表 → 错误分类。
|
||||
"""
|
||||
raw = (input_name or "").strip()
|
||||
if not raw:
|
||||
return PlatformResolveResult(
|
||||
error_code="INVALID_PLATFORM",
|
||||
message="平台名不能为空。",
|
||||
)
|
||||
|
||||
builtin = resolve_platform_key(raw)
|
||||
if builtin:
|
||||
return PlatformResolveResult(platform_key=builtin)
|
||||
|
||||
close_conn = False
|
||||
if conn is None:
|
||||
from db.connection import get_conn, init_db
|
||||
|
||||
init_db()
|
||||
conn = get_conn()
|
||||
close_conn = True
|
||||
try:
|
||||
db_result = _resolve_platform_from_db(conn, raw)
|
||||
if db_result.ok or db_result.error_code:
|
||||
return db_result
|
||||
finally:
|
||||
if close_conn:
|
||||
conn.close()
|
||||
|
||||
if not is_valid_platform_key_format(raw):
|
||||
return PlatformResolveResult(
|
||||
error_code="INVALID_PLATFORM_KEY",
|
||||
message=(
|
||||
f"平台 key 格式非法:「{raw}」。"
|
||||
"建议使用小写字母、数字、下划线或连字符,例如 jiangchang。"
|
||||
),
|
||||
)
|
||||
|
||||
key_hint = raw.lower()
|
||||
return PlatformResolveResult(
|
||||
error_code="PLATFORM_NOT_REGISTERED",
|
||||
message=(
|
||||
f"平台 {key_hint} 尚未注册,请先执行 "
|
||||
f"account platform ensure --key {key_hint} --display-name <名称> [--url <url>]"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def get_platform_spec(platform_key: str, conn=None) -> dict[str, Any]:
|
||||
"""内置 PLATFORMS 优先结构;自定义平台从 DB platforms 表读取。"""
|
||||
spec = PLATFORMS.get(platform_key)
|
||||
if spec:
|
||||
return dict(spec)
|
||||
|
||||
close_conn = False
|
||||
if conn is None:
|
||||
from db.connection import get_conn, init_db
|
||||
|
||||
init_db()
|
||||
conn = get_conn()
|
||||
close_conn = True
|
||||
try:
|
||||
from db.accounts_repo import get_platform_from_db
|
||||
|
||||
plat = get_platform_from_db(conn, platform_key)
|
||||
if plat:
|
||||
return {
|
||||
"display_name": plat["display_name"],
|
||||
"domain": plat.get("domain") or "generic",
|
||||
"provider_code": plat.get("provider_code") or platform_key,
|
||||
"default_url": plat.get("default_url") or "",
|
||||
"aliases": plat.get("aliases") or [],
|
||||
"capabilities": plat.get("capabilities") or {},
|
||||
}
|
||||
finally:
|
||||
if close_conn:
|
||||
conn.close()
|
||||
return {}
|
||||
|
||||
|
||||
def get_platform(key: str) -> Optional[dict[str, Any]]:
|
||||
"""Return the full platform spec dict for a validated key."""
|
||||
"""Return the full platform spec dict for a validated built-in key."""
|
||||
return PLATFORMS.get(key)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user