chore: auto release commit (2026-06-19 09:53:29)
All checks were successful
技能自动化发布 / release (push) Successful in 7s

This commit is contained in:
2026-06-19 09:53:29 +08:00
parent cb980704bf
commit 23f4a2c11a
5 changed files with 555 additions and 53 deletions

View File

@@ -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 表中解析:精确 keyenabled=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)