from __future__ import annotations import httpx import json import re from datetime import datetime, timezone from typing import Any from fastapi import Depends, HTTPException, Query from pydantic import BaseModel, Field class OneLinerProfileRequest(BaseModel): project_id: str = "" assistant_id: str = "" display_name: str = "OneLiner" long_term_goal: str = "" notes: str = "" default_platform: str = "" config: dict[str, Any] = Field(default_factory=dict) reason: str = "" class OneLinerProfileRollbackRequest(BaseModel): project_id: str = "" version_id: str reason: str = "" class OneLinerSessionCreateRequest(BaseModel): project_id: str = "" title: str = "" preferred_platform: str = "" initial_message: str = "" class OneLinerMessageRequest(BaseModel): content: str project_id: str = "" platform: str = "" target_account_id: str = "" remember_preference: bool = False class PlatformAgentProfileRequest(BaseModel): project_id: str = "" assistant_id: str = "" name: str = "" mission: str = "" notes: str = "" status: str = "active" config: dict[str, Any] = Field(default_factory=dict) reason: str = "" class PlatformAgentProfileRollbackRequest(BaseModel): project_id: str = "" version_id: str reason: str = "" class AgentMemoryUpsertRequest(BaseModel): project_id: str = "" subject_type: str = "project" subject_id: str = "" memory_key: str title: str = "" summary: str details: dict[str, Any] = Field(default_factory=dict) confidence: float = Field(default=0.7, ge=0.0, le=1.0) class AgentSkillUpsertRequest(BaseModel): project_id: str = "" skill_key: str name: str status: str = "draft" method: dict[str, Any] = Field(default_factory=dict) test_spec: dict[str, Any] = Field(default_factory=dict) last_result: dict[str, Any] = Field(default_factory=dict) success_count: int = Field(default=0, ge=0) failure_count: int = Field(default=0, ge=0) last_score: float = 0.0 class AdminIncidentReviewRequest(BaseModel): status: str = "reviewed" review_notes: str = "" class PlatformAgentSelfCheckRequest(BaseModel): project_id: str = "" sample_limit: int = Field(default=3, ge=1, le=12) remember_summary: bool = True class PlatformSkillReviewRequest(BaseModel): project_id: str = "" accepted: bool = True score: float = Field(default=0.8, ge=0.0, le=1.0) status: str = "" summary: str = "" review_notes: str = "" class OneLinerActionExecuteRequest(BaseModel): action_key: str project_id: str = "" platform: str = "" session_id: str = "" payload: dict[str, Any] = Field(default_factory=dict) class OneLinerActionDefinitionRequest(BaseModel): label: str = "" description: str = "" category: str = "custom" status: str = "enabled" admin_only: bool | None = None requires_platform: bool | None = None config: dict[str, Any] = Field(default_factory=dict) class AdminFixPlanRequest(BaseModel): incident_id: str = "" scope: str = "plan" notes: str = "" class AdminFixRunReviewRequest(BaseModel): review_status: str = "approved" review_notes: str = "" class PlatformSkillRollbackRequest(BaseModel): project_id: str = "" version_id: str = "" class TenantQuotaRequest(BaseModel): package_label: str = "" monthly_budget_cents: int = Field(default=0, ge=0) storage_limit_bytes: int = Field(default=0, ge=0) analysis_quota: int = Field(default=0, ge=0) copy_quota: int = Field(default=0, ge=0) ai_video_quota: int = Field(default=0, ge=0) real_cut_quota: int = Field(default=0, ge=0) recorder_quota: int = Field(default=0, ge=0) enabled: bool = True config: dict[str, Any] = Field(default_factory=dict) class AgentPolicyUpsertRequest(BaseModel): project_id: str = "" target_user_id: str = "" target_project_id: str = "" platform: str = "" title: str = "" summary: str = "" policy: dict[str, Any] = Field(default_factory=dict) effect_mode: str = "ongoing" starts_at: str = "" ends_at: str = "" config: dict[str, Any] = Field(default_factory=dict) reason: str = "" class AgentPolicyRollbackRequest(BaseModel): project_id: str = "" target_user_id: str = "" target_project_id: str = "" platform: str = "" version_id: str reason: str = "" class AgentRunCreateRequest(BaseModel): project_id: str = "" session_id: str = "" source_screen: str = "dashboard" source_action_key: str = "" title: str = "" summary: str = "" intent_key: str = "custom" platform: str = "" platform_scope: str = "single_platform" delivery_mode: str = "hybrid" scheduling_mode: str = "queued" plan_request: dict[str, Any] = Field(default_factory=dict) payload: dict[str, Any] = Field(default_factory=dict) class AgentRunConfirmRequest(BaseModel): reason: str = "" class AgentRunCancelRequest(BaseModel): reason: str = "" class AgentRunRetryRequest(BaseModel): reason: str = "" INTENT_ACTIONS: dict[str, list[dict[str, Any]]] = { "create_project": [{"key": "goto-intake", "label": "去我的项目", "kind": "navigate"}], "create_assistant": [{"key": "open-create-assistant", "label": "创建 Agent", "kind": "ui_action"}], "import_homepage": [{"key": "open-import-homepage", "label": "导入主页", "kind": "ui_action"}], "track_account": [{"key": "open-track-selected-account", "label": "跟踪当前账号", "kind": "ui_action"}], "analyze_account": [{"key": "analyze-selected-account", "label": "分析当前账号", "kind": "ui_action"}], "analyze_top_videos": [{"key": "analyze-top-videos", "label": "分析高分作品", "kind": "ui_action"}], "generate_copy": [{"key": "open-generate-copy", "label": "生成文案", "kind": "ui_action"}], "ai_video": [{"key": "open-ai-video", "label": "做 AI 视频", "kind": "ui_action"}], "real_cut": [{"key": "open-real-cut", "label": "做实拍剪辑", "kind": "ui_action"}], "review": [{"key": "goto-review", "label": "去发布与复盘", "kind": "navigate"}], "live_recorder": [{"key": "open-live-recorder", "label": "打开录制控制", "kind": "ui_action"}], "storage_status": [{"key": "goto-production", "label": "查看生产与存储", "kind": "navigate"}], "ops_admin": [{"key": "goto-automation", "label": "去自动流程", "kind": "navigate"}], } INTENT_LABELS = { "create_project": "创建项目", "create_assistant": "创建 Agent", "import_homepage": "导入主页", "track_account": "跟踪账号", "analyze_account": "分析账号", "analyze_top_videos": "分析高分作品", "generate_copy": "生成文案", "ai_video": "生成 AI 视频", "real_cut": "实拍剪辑", "review": "发布复盘", "live_recorder": "直播录制", "storage_status": "查看存储", "ops_admin": "运维巡检", "custom": "自定义任务", } ACTION_REGISTRY_DEFAULTS: dict[str, dict[str, Any]] = { "platform-self-check": { "label": "运行平台自检", "description": "检查当前平台 Agent 的路由、执行 Agent、技能和记忆是否达到可运行状态。", "category": "platform", "handler_key": "platform-self-check", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {}, }, "storage-status": { "label": "查看当前存储状态", "description": "查看当前租户项目的 jobs、downloads、NAS 目录占用和最近产物。", "category": "storage", "handler_key": "storage-status", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "live-recorder-status": { "label": "查看录制状态", "description": "查看当前租户名下的录制源、运行状态和最近录像文件。", "category": "recorder", "handler_key": "live-recorder-status", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "scan-admin-ops": { "label": "重新扫描故障", "description": "让管理员运维 Agent 重新汇总当前失败任务与集成异常。", "category": "admin_ops", "handler_key": "scan-admin-ops", "status": "enabled", "admin_only": True, "requires_platform": False, "config": {}, }, "generate-copy": { "label": "直接生成一版文案", "description": "基于当前项目、执行 Agent 和最近上下文直接生成一版文案。", "category": "content", "handler_key": "generate-copy", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "review-draft": { "label": "生成复盘草稿", "description": "基于最近完成任务自动生成或回收一版复盘草稿。", "category": "review", "handler_key": "review-draft", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "import-homepage": { "label": "直接导入主页", "description": "把主页导入当前项目并触发内容源同步。", "category": "intake", "handler_key": "import-homepage", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"auto_trigger_analysis": True}, }, "analyze-top-videos": { "label": "直接分析高分作品", "description": "拆解当前平台账号的高分作品,并把结论沉淀到平台记忆。", "category": "analysis", "handler_key": "analyze-top-videos", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"top_video_count": 4}, }, "analyze-account": { "label": "直接分析账号", "description": "基于当前平台账号直接生成账号分析报告与下一步建议。", "category": "analysis", "handler_key": "analyze-account", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"max_videos": 6}, }, "track-account": { "label": "直接加入跟踪", "description": "把当前平台账号加入跟踪,并立即触发一次同步。", "category": "tracking", "handler_key": "track-account", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"refresh_now": True}, }, "refresh-tracking": { "label": "直接同步跟踪池", "description": "批量触发当前平台已跟踪账号的同步任务。", "category": "tracking", "handler_key": "refresh-tracking", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {}, }, "mark-tracking-read": { "label": "直接标记日报已读", "description": "把当前平台跟踪日报更新为已读,下次从新的时间点继续汇总。", "category": "tracking", "handler_key": "mark-tracking-read", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {}, }, "search-similar-accounts": { "label": "直接查相似账号", "description": "基于当前平台账号直接生成一批相似候选,并沉淀到当前项目。", "category": "analysis", "handler_key": "search-similar-accounts", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"max_candidates": 8}, }, "save-benchmark-link": { "label": "直接存对标关系", "description": "把当前相似候选直接加入对标关系,便于后续持续跟踪和拆解。", "category": "analysis", "handler_key": "save-benchmark-link", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"relation_type": "benchmark"}, }, "create-assistant": { "label": "直接创建 Agent", "description": "根据当前项目和平台上下文,直接创建可继续编辑的 Agent。", "category": "agent", "handler_key": "create-assistant", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "create-ai-video": { "label": "直接创建 AI 视频", "description": "基于最近可用源任务直接创建 AI 视频链任务。", "category": "production", "handler_key": "create-ai-video", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "create-real-cut": { "label": "直接创建实拍剪辑", "description": "基于最近可用源任务直接创建实拍剪辑链任务。", "category": "production", "handler_key": "create-real-cut", "status": "enabled", "admin_only": False, "requires_platform": False, "config": {}, }, "save-live-recorder-source": { "label": "直接保存录制源", "description": "把直播源直接保存到当前租户的 NAS 录制配置。", "category": "recorder", "handler_key": "save-live-recorder-source", "status": "enabled", "admin_only": False, "requires_platform": True, "config": {"auto_start": True}, }, } USAGE_COST_DEFAULTS: dict[str, dict[str, Any]] = { "analysis": {"cost_cents": 6, "quota_field": "analysis_quota"}, "content_source_sync": {"cost_cents": 8, "quota_field": "analysis_quota"}, "copy": {"cost_cents": 3, "quota_field": "copy_quota"}, "review": {"cost_cents": 1, "quota_field": "analysis_quota"}, "ai_video": {"cost_cents": 30, "quota_field": "ai_video_quota"}, "real_cut": {"cost_cents": 20, "quota_field": "real_cut_quota"}, "live_recorder": {"cost_cents": 2, "quota_field": "recorder_quota"}, } TENANT_QUOTA_PACKAGE_PRESETS: dict[str, dict[str, Any]] = { "trial": { "title": "试用套餐", "description": "适合先跑通主流程的小规模项目,预算和动作池会优先保护试错成本。", "focus": "先验证项目是否跑得通,再决定是否扩容。", "warn_threshold": 0.7, "monthly_budget_cents": 9900, "storage_limit_bytes": 5 * 1024 * 1024 * 1024, "analysis_quota": 30, "copy_quota": 60, "ai_video_quota": 2, "real_cut_quota": 1, "recorder_quota": 4, }, "growth": { "title": "增长套餐", "description": "适合已经形成固定内容节奏的项目,兼顾分析、文案和视频动作的持续投放。", "focus": "先把稳定增长跑顺,再看哪里需要单独加码。", "warn_threshold": 0.8, "monthly_budget_cents": 49900, "storage_limit_bytes": 20 * 1024 * 1024 * 1024, "analysis_quota": 160, "copy_quota": 320, "ai_video_quota": 12, "real_cut_quota": 8, "recorder_quota": 20, }, "scale": { "title": "规模套餐", "description": "适合多账号、多批次的量产项目,预算、存储和视频动作都会按高负载配置。", "focus": "优先保证量产吞吐,再按平台专项做局部优化。", "warn_threshold": 0.85, "monthly_budget_cents": 199000, "storage_limit_bytes": 80 * 1024 * 1024 * 1024, "analysis_quota": 800, "copy_quota": 1600, "ai_video_quota": 40, "real_cut_quota": 24, "recorder_quota": 80, }, } ACTION_USAGE_KEYS: dict[str, str] = { "generate-copy": "copy", "review-draft": "review", "import-homepage": "content_source_sync", "analyze-top-videos": "analysis", "analyze-account": "analysis", "track-account": "content_source_sync", "refresh-tracking": "content_source_sync", "search-similar-accounts": "analysis", "create-ai-video": "ai_video", "create-real-cut": "real_cut", "save-live-recorder-source": "live_recorder", } def register_oneliner_routes(app: Any, legacy: Any) -> None: def now() -> str: return legacy.utc_now() def make_id(prefix: str) -> str: return legacy.make_id(prefix) def _parse_json(raw: str | None, fallback: Any) -> Any: cleaned = str(raw or "").strip() if not cleaned: return fallback try: return json.loads(cleaned) except json.JSONDecodeError: return fallback def _dump(value: Any) -> str: return json.dumps(value or {}, ensure_ascii=False) def _normalize_package_label(value: Any) -> str: label = str(value or "").strip().lower() if not label: return "custom" return label if label in TENANT_QUOTA_PACKAGE_PRESETS else "custom" def _clamp_warn_threshold(value: Any, fallback: float = 0.8) -> float: try: parsed = float(value) except (TypeError, ValueError): parsed = float(fallback) if parsed <= 0: parsed = float(fallback) return max(0.1, min(parsed, 0.95)) def _tenant_quota_package_label(data: dict[str, Any]) -> str: config = _parse_json(data.get("config_json"), {}) label = _normalize_package_label(config.get("package_label")) if label != "custom": return label for preset_label, preset_values in TENANT_QUOTA_PACKAGE_PRESETS.items(): numeric_fields = ( "monthly_budget_cents", "storage_limit_bytes", "analysis_quota", "copy_quota", "ai_video_quota", "real_cut_quota", "recorder_quota", ) if all(int(data.get(field) or 0) == int(preset_values.get(field) or 0) for field in numeric_fields): return preset_label return "custom" def _tenant_quota_config(data: dict[str, Any]) -> dict[str, Any]: config = _parse_json(data.get("config_json"), {}) package_label = _tenant_quota_package_label(data) config["package_label"] = package_label preset = TENANT_QUOTA_PACKAGE_PRESETS.get(package_label) config["warn_threshold"] = _clamp_warn_threshold( config.get("warn_threshold", preset.get("warn_threshold", 0.8) if preset else 0.8), preset.get("warn_threshold", 0.8) if preset else 0.8, ) if preset: config.update( { "package_title": preset["title"], "package_description": preset["description"], "package_focus": preset["focus"], "package_is_preset": True, "package_defaults": { "monthly_budget_cents": int(preset["monthly_budget_cents"]), "storage_limit_bytes": int(preset["storage_limit_bytes"]), "analysis_quota": int(preset["analysis_quota"]), "copy_quota": int(preset["copy_quota"]), "ai_video_quota": int(preset["ai_video_quota"]), "real_cut_quota": int(preset["real_cut_quota"]), "recorder_quota": int(preset["recorder_quota"]), }, } ) else: config.update( { "package_title": "自定义套餐", "package_description": "按当前项目的预算、动作池和阶段手动配置套餐。", "package_focus": "适合已经明确成本模型或需要特殊额度策略的项目。", "package_is_preset": False, "package_defaults": {}, } ) return config def _tenant_quota_values(request: TenantQuotaRequest, package_label: str) -> dict[str, int]: preset = TENANT_QUOTA_PACKAGE_PRESETS.get(package_label) if preset: return { "monthly_budget_cents": int(preset["monthly_budget_cents"]), "storage_limit_bytes": int(preset["storage_limit_bytes"]), "analysis_quota": int(preset["analysis_quota"]), "copy_quota": int(preset["copy_quota"]), "ai_video_quota": int(preset["ai_video_quota"]), "real_cut_quota": int(preset["real_cut_quota"]), "recorder_quota": int(preset["recorder_quota"]), } return { "monthly_budget_cents": int(request.monthly_budget_cents or 0), "storage_limit_bytes": int(request.storage_limit_bytes or 0), "analysis_quota": int(request.analysis_quota or 0), "copy_quota": int(request.copy_quota or 0), "ai_video_quota": int(request.ai_video_quota or 0), "real_cut_quota": int(request.real_cut_quota or 0), "recorder_quota": int(request.recorder_quota or 0), } def _bool_flag(value: Any) -> bool: if isinstance(value, bool): return value if value in {1, "1", "true", "True", "yes", "on"}: return True return False def _current_cycle_start() -> str: current = datetime.now(timezone.utc) return current.replace(day=1, hour=0, minute=0, second=0, microsecond=0).isoformat().replace("+00:00", "Z") def _parse_policy_datetime(value: str | None) -> datetime | None: text = str(value or "").strip() if not text: return None try: normalized = text.replace("Z", "+00:00") parsed = datetime.fromisoformat(normalized) if parsed.tzinfo is None: parsed = parsed.replace(tzinfo=timezone.utc) return parsed.astimezone(timezone.utc) except ValueError: return None def ensure_schema() -> None: schema = """ CREATE TABLE IF NOT EXISTS oneliner_profiles ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', assistant_id TEXT NOT NULL DEFAULT '', display_name TEXT NOT NULL DEFAULT 'OneLiner', long_term_goal TEXT NOT NULL DEFAULT '', notes TEXT NOT NULL DEFAULT '', default_platform TEXT NOT NULL DEFAULT '', config_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(assistant_id) REFERENCES assistants(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS oneliner_profile_versions ( id TEXT PRIMARY KEY, profile_id TEXT NOT NULL, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', assistant_id TEXT NOT NULL DEFAULT '', version_no INTEGER NOT NULL DEFAULT 1, display_name TEXT NOT NULL DEFAULT 'OneLiner', long_term_goal TEXT NOT NULL DEFAULT '', notes TEXT NOT NULL DEFAULT '', default_platform TEXT NOT NULL DEFAULT '', config_json TEXT NOT NULL DEFAULT '{}', summary TEXT NOT NULL DEFAULT '', reason TEXT NOT NULL DEFAULT '', source_type TEXT NOT NULL DEFAULT 'user', rollback_from_version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, UNIQUE(profile_id, version_no), FOREIGN KEY(profile_id) REFERENCES oneliner_profiles(id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS oneliner_profile_audit_logs ( id TEXT PRIMARY KEY, profile_id TEXT NOT NULL, version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', action_key TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(profile_id) REFERENCES oneliner_profiles(id) ON DELETE CASCADE, FOREIGN KEY(version_id) REFERENCES oneliner_profile_versions(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS oneliner_sessions ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', profile_id TEXT, title TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active', preferred_platform TEXT NOT NULL DEFAULT '', last_platform TEXT NOT NULL DEFAULT '', last_intent_key TEXT NOT NULL DEFAULT '', last_message_at TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(profile_id) REFERENCES oneliner_profiles(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS oneliner_messages ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL DEFAULT '', plan_json TEXT NOT NULL DEFAULT '{}', result_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(session_id) REFERENCES oneliner_sessions(id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS platform_agent_profiles ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', platform TEXT NOT NULL, assistant_id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', mission TEXT NOT NULL DEFAULT '', notes TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active', config_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id, platform), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(assistant_id) REFERENCES assistants(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS platform_agent_profile_versions ( id TEXT PRIMARY KEY, profile_id TEXT NOT NULL, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', platform TEXT NOT NULL DEFAULT '', assistant_id TEXT NOT NULL DEFAULT '', version_no INTEGER NOT NULL DEFAULT 1, name TEXT NOT NULL DEFAULT '', mission TEXT NOT NULL DEFAULT '', notes TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active', config_json TEXT NOT NULL DEFAULT '{}', summary TEXT NOT NULL DEFAULT '', reason TEXT NOT NULL DEFAULT '', source_type TEXT NOT NULL DEFAULT 'user_update', rollback_from_version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, UNIQUE(profile_id, version_no), FOREIGN KEY(profile_id) REFERENCES platform_agent_profiles(id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(assistant_id) REFERENCES assistants(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS platform_agent_profile_audit_logs ( id TEXT PRIMARY KEY, profile_id TEXT NOT NULL, version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', action_key TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(profile_id) REFERENCES platform_agent_profiles(id) ON DELETE CASCADE, FOREIGN KEY(version_id) REFERENCES platform_agent_profile_versions(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS agent_memories ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', agent_scope TEXT NOT NULL, platform TEXT NOT NULL DEFAULT '', subject_type TEXT NOT NULL DEFAULT 'project', subject_id TEXT NOT NULL DEFAULT '', memory_key TEXT NOT NULL, title TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', confidence REAL NOT NULL DEFAULT 0.7, last_validated_at TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id, agent_scope, platform, subject_type, subject_id, memory_key), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS agent_skills ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', agent_scope TEXT NOT NULL, platform TEXT NOT NULL DEFAULT '', parent_skill_id TEXT NOT NULL DEFAULT '', skill_key TEXT NOT NULL, name TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'draft', method_json TEXT NOT NULL DEFAULT '{}', test_spec_json TEXT NOT NULL DEFAULT '{}', last_result_json TEXT NOT NULL DEFAULT '{}', success_count INTEGER NOT NULL DEFAULT 0, failure_count INTEGER NOT NULL DEFAULT 0, last_score REAL NOT NULL DEFAULT 0, last_validated_at TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id, agent_scope, platform, skill_key), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS agent_policy_scopes ( id TEXT PRIMARY KEY, scope_kind TEXT NOT NULL, subject_user_id TEXT NOT NULL DEFAULT '', subject_project_id TEXT NOT NULL DEFAULT '', platform TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active', title TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', current_version_id TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(scope_kind, subject_user_id, subject_project_id, platform) ); CREATE TABLE IF NOT EXISTS agent_policy_versions ( id TEXT PRIMARY KEY, scope_id TEXT NOT NULL, scope_kind TEXT NOT NULL, subject_user_id TEXT NOT NULL DEFAULT '', subject_project_id TEXT NOT NULL DEFAULT '', platform TEXT NOT NULL DEFAULT '', version_no INTEGER NOT NULL DEFAULT 1, title TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', policy_json TEXT NOT NULL DEFAULT '{}', reason TEXT NOT NULL DEFAULT '', source_type TEXT NOT NULL DEFAULT 'user', rollback_from_version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, UNIQUE(scope_id, version_no) ); CREATE TABLE IF NOT EXISTS agent_policy_effectivity ( id TEXT PRIMARY KEY, scope_id TEXT NOT NULL, version_id TEXT NOT NULL, effect_mode TEXT NOT NULL DEFAULT 'ongoing', starts_at TEXT NOT NULL DEFAULT '', ends_at TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'active', config_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(version_id) ); CREATE TABLE IF NOT EXISTS agent_policy_audit_logs ( id TEXT PRIMARY KEY, scope_id TEXT NOT NULL DEFAULT '', version_id TEXT NOT NULL DEFAULT '', actor_user_id TEXT NOT NULL DEFAULT '', action_key TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS agent_runs ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', session_id TEXT NOT NULL DEFAULT '', source_screen TEXT NOT NULL DEFAULT '', source_action_key TEXT NOT NULL DEFAULT '', title TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', intent_key TEXT NOT NULL DEFAULT 'custom', platform TEXT NOT NULL DEFAULT '', platform_scope TEXT NOT NULL DEFAULT 'single_platform', delivery_mode TEXT NOT NULL DEFAULT 'hybrid', run_status TEXT NOT NULL DEFAULT 'needs_confirmation', scheduling_mode TEXT NOT NULL DEFAULT 'queued', active_executor_key TEXT NOT NULL DEFAULT 'main_agent', plan_json TEXT NOT NULL DEFAULT '{}', governance_json TEXT NOT NULL DEFAULT '{}', result_json TEXT NOT NULL DEFAULT '{}', status_summary TEXT NOT NULL DEFAULT '', needs_user_input INTEGER NOT NULL DEFAULT 1, blocked_reason TEXT NOT NULL DEFAULT '', active_admin_override_notice_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, started_at TEXT NOT NULL DEFAULT '', finished_at TEXT NOT NULL DEFAULT '', FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(session_id) REFERENCES oneliner_sessions(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS agent_run_events ( id TEXT PRIMARY KEY, run_id TEXT NOT NULL, event_type TEXT NOT NULL, summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(run_id) REFERENCES agent_runs(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS admin_ops_incidents ( id TEXT PRIMARY KEY, tenant_user_id TEXT NOT NULL DEFAULT '', tenant_project_id TEXT NOT NULL DEFAULT '', source_type TEXT NOT NULL, source_id TEXT NOT NULL DEFAULT '', severity TEXT NOT NULL DEFAULT 'warn', title TEXT NOT NULL, summary TEXT NOT NULL DEFAULT '', payload_json TEXT NOT NULL DEFAULT '{}', status TEXT NOT NULL DEFAULT 'open', assigned_to TEXT NOT NULL DEFAULT '', reviewed_by TEXT NOT NULL DEFAULT '', review_notes TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(source_type, source_id, title), FOREIGN KEY(tenant_user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(tenant_project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(assigned_to) REFERENCES accounts(id) ON DELETE SET NULL, FOREIGN KEY(reviewed_by) REFERENCES accounts(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS admin_ops_audit_logs ( id TEXT PRIMARY KEY, actor_user_id TEXT NOT NULL DEFAULT '', incident_id TEXT NOT NULL DEFAULT '', action_key TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'recorded', summary TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(actor_user_id) REFERENCES accounts(id) ON DELETE SET NULL, FOREIGN KEY(incident_id) REFERENCES admin_ops_incidents(id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS oneliner_action_definitions ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', action_key TEXT NOT NULL, handler_key TEXT NOT NULL DEFAULT '', label TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', category TEXT NOT NULL DEFAULT 'custom', status TEXT NOT NULL DEFAULT 'enabled', admin_only INTEGER NOT NULL DEFAULT 0, requires_platform INTEGER NOT NULL DEFAULT 0, config_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id, action_key), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS agent_skill_versions ( id TEXT PRIMARY KEY, skill_id TEXT NOT NULL, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', agent_scope TEXT NOT NULL, platform TEXT NOT NULL DEFAULT '', version_no INTEGER NOT NULL DEFAULT 1, snapshot_reason TEXT NOT NULL DEFAULT 'updated', snapshot_json TEXT NOT NULL DEFAULT '{}', actor_user_id TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL, UNIQUE(skill_id, version_no), FOREIGN KEY(skill_id) REFERENCES agent_skills(id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY(actor_user_id) REFERENCES accounts(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS admin_ops_fix_runs ( id TEXT PRIMARY KEY, incident_id TEXT NOT NULL, actor_user_id TEXT NOT NULL DEFAULT '', tenant_user_id TEXT NOT NULL DEFAULT '', tenant_project_id TEXT NOT NULL DEFAULT '', plan_scope TEXT NOT NULL DEFAULT 'plan', status TEXT NOT NULL DEFAULT 'planned', audit_status TEXT NOT NULL DEFAULT 'pending', review_notes TEXT NOT NULL DEFAULT '', plan_json TEXT NOT NULL DEFAULT '{}', verification_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, FOREIGN KEY(incident_id) REFERENCES admin_ops_incidents(id) ON DELETE CASCADE, FOREIGN KEY(actor_user_id) REFERENCES accounts(id) ON DELETE SET NULL, FOREIGN KEY(tenant_user_id) REFERENCES accounts(id) ON DELETE SET NULL, FOREIGN KEY(tenant_project_id) REFERENCES projects(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS tenant_quota_profiles ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', monthly_budget_cents INTEGER NOT NULL DEFAULT 0, storage_limit_bytes INTEGER NOT NULL DEFAULT 0, analysis_quota INTEGER NOT NULL DEFAULT 0, copy_quota INTEGER NOT NULL DEFAULT 0, ai_video_quota INTEGER NOT NULL DEFAULT 0, real_cut_quota INTEGER NOT NULL DEFAULT 0, recorder_quota INTEGER NOT NULL DEFAULT 0, enabled INTEGER NOT NULL DEFAULT 1, config_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(user_id, project_id), FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS tenant_usage_ledger ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, project_id TEXT NOT NULL DEFAULT '', category TEXT NOT NULL, quantity INTEGER NOT NULL DEFAULT 1, cost_cents INTEGER NOT NULL DEFAULT 0, reference_type TEXT NOT NULL DEFAULT '', reference_id TEXT NOT NULL DEFAULT '', details_json TEXT NOT NULL DEFAULT '{}', created_at TEXT NOT NULL, FOREIGN KEY(user_id) REFERENCES accounts(id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE SET NULL ); """ with legacy.db.session() as conn: conn.executescript(schema) ensure_schema() @app.on_event("startup") def _startup_oneliner_schema() -> None: ensure_schema() def _resolve_project(account: dict[str, Any], project_id: str | None) -> dict[str, Any]: return legacy.resolve_target_project(account["id"], project_id or None, username=account["username"]) def _resolve_project_for_read(account: dict[str, Any], project_id: str | None) -> dict[str, Any] | None: if project_id: return legacy.resolve_target_project(account["id"], project_id, username=account["username"]) return legacy.db.fetch_one( "SELECT * FROM projects WHERE user_id = ? ORDER BY created_at ASC LIMIT 1", (account["id"],), ) def _resolve_assistant(account: dict[str, Any], assistant_id: str | None, project_id: str = "") -> dict[str, Any] | None: return legacy.resolve_target_assistant(account["id"], assistant_id or None, project_id) def _safe_platform(platform_value: str | None, fallback: str = "douyin") -> str: return legacy.ensure_domestic_platform(platform_value or fallback, allow_blank=not fallback) or fallback def _route_supported(path: str) -> bool: return any(getattr(route, "path", "") == path for route in app.routes) def _platform_route_checks(platform: str) -> list[dict[str, Any]]: checks = [ ("accounts", f"/v2/{platform}/accounts"), ("workspace", f"/v2/{platform}/accounts/{{account_id}}/workspace"), ("videos", f"/v2/{platform}/accounts/{{account_id}}/videos"), ("analyze_account", f"/v2/{platform}/accounts/{{account_id}}/analysis"), ("analyze_top_videos", f"/v2/{platform}/accounts/{{account_id}}/videos/analyze-top"), ("similar_searches", f"/v2/{platform}/similar-searches"), ("benchmark_links", f"/v2/{platform}/accounts/{{account_id}}/benchmark-links"), ] return [ { "key": key, "path": path, "ok": _route_supported(path), } for key, path in checks ] def _fetch_profile_row(account: dict[str, Any], project_id: str = "") -> dict[str, Any] | None: return legacy.db.fetch_one( "SELECT * FROM oneliner_profiles WHERE user_id = ? AND project_id = ?", (account["id"], project_id), ) def _summarize_oneliner_profile(row: dict[str, Any] | None) -> str: def _limit(text: str, limit: int) -> str: value = str(text or "").strip() if len(value) <= limit: return value return f"{value[: max(limit - 1, 0)].rstrip()}…" data = row or {} assistant_id = str(data.get("assistant_id") or "").strip() assistant_row = legacy.db.fetch_one("SELECT * FROM assistants WHERE id = ?", (assistant_id,)) if assistant_id else None assistant_name = (assistant_row or {}).get("name", "").strip() parts = [ f"默认平台 {legacy.platform_label(data.get('default_platform', '') or 'douyin')}", "已绑定执行 Agent" if assistant_id else "暂未绑定执行 Agent", ] if assistant_name: parts.append(f"执行 Agent 为 {assistant_name}") long_term_goal = str(data.get("long_term_goal") or "").strip() if long_term_goal: parts.append(_limit(long_term_goal, 36)) notes = str(data.get("notes") or "").strip() if notes: parts.append(f"备注 {_limit(notes, 32)}") return ",".join(parts[:4]) def _oneliner_profile_version_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None assistant = None if row.get("assistant_id"): assistant_row = legacy.db.fetch_one("SELECT * FROM assistants WHERE id = ?", (row["assistant_id"],)) if assistant_row: assistant = legacy.assistant_payload(assistant_row) return { "id": row["id"], "profile_id": row.get("profile_id", ""), "user_id": row.get("user_id", ""), "project_id": row.get("project_id", ""), "assistant_id": row.get("assistant_id", ""), "version_no": int(row.get("version_no") or 0), "display_name": row.get("display_name", "OneLiner"), "long_term_goal": row.get("long_term_goal", ""), "notes": row.get("notes", ""), "default_platform": row.get("default_platform", ""), "config": _parse_json(row.get("config_json"), {}), "summary": row.get("summary", ""), "reason": row.get("reason", ""), "source_type": row.get("source_type", ""), "rollback_from_version_id": row.get("rollback_from_version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "assistant": assistant, "created_at": row.get("created_at", ""), } def _oneliner_profile_audit_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None version_row = legacy.db.fetch_one("SELECT * FROM oneliner_profile_versions WHERE id = ?", (row.get("version_id", ""),)) if row.get("version_id") else None return { "id": row["id"], "profile_id": row.get("profile_id", ""), "version_id": row.get("version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "action_key": row.get("action_key", ""), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "version": _oneliner_profile_version_payload(version_row), "created_at": row.get("created_at", ""), } def _list_oneliner_profile_versions(profile_row: dict[str, Any] | None) -> list[dict[str, Any]]: if not profile_row: return [] rows = legacy.db.fetch_all( """ SELECT * FROM oneliner_profile_versions WHERE profile_id = ? ORDER BY version_no DESC, created_at DESC """, (profile_row["id"],), ) return [_oneliner_profile_version_payload(row) for row in rows if row] def _list_oneliner_profile_audits(profile_row: dict[str, Any] | None, *, limit: int = 12) -> list[dict[str, Any]]: if not profile_row: return [] rows = legacy.db.fetch_all( """ SELECT * FROM oneliner_profile_audit_logs WHERE profile_id = ? ORDER BY created_at DESC LIMIT ? """, (profile_row["id"], limit), ) return [_oneliner_profile_audit_payload(row) for row in rows if row] def _current_oneliner_profile_version_row(profile_row: dict[str, Any] | None) -> dict[str, Any] | None: if not profile_row: return None return legacy.db.fetch_one( """ SELECT * FROM oneliner_profile_versions WHERE profile_id = ? ORDER BY version_no DESC, created_at DESC LIMIT 1 """, (profile_row["id"],), ) def _log_oneliner_profile_audit( *, profile_id: str, version_id: str, actor_user_id: str, action_key: str, summary: str, details: dict[str, Any] | None = None, ) -> dict[str, Any]: audit_id = make_id("oneliner_profile_audit") legacy.db.execute( """ INSERT INTO oneliner_profile_audit_logs ( id, profile_id, version_id, actor_user_id, action_key, summary, details_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, ( audit_id, profile_id, version_id, actor_user_id, action_key, summary, _dump(details or {}), now(), ), ) row = legacy.db.fetch_one("SELECT * FROM oneliner_profile_audit_logs WHERE id = ?", (audit_id,)) assert row is not None return _oneliner_profile_audit_payload(row) def _create_oneliner_profile_version( profile_row: dict[str, Any], *, actor_user_id: str, source_type: str, reason: str, rollback_from_version_id: str = "", ) -> dict[str, Any]: current = legacy.db.fetch_one( "SELECT COALESCE(MAX(version_no), 0) AS max_version FROM oneliner_profile_versions WHERE profile_id = ?", (profile_row["id"],), ) version_no = int((current or {}).get("max_version") or 0) + 1 version_id = make_id("oneliner_profile_ver") summary = _summarize_oneliner_profile(profile_row) legacy.db.execute( """ INSERT INTO oneliner_profile_versions ( id, profile_id, user_id, project_id, assistant_id, version_no, display_name, long_term_goal, notes, default_platform, config_json, summary, reason, source_type, rollback_from_version_id, actor_user_id, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( version_id, profile_row["id"], profile_row.get("user_id", ""), profile_row.get("project_id", ""), profile_row.get("assistant_id", ""), version_no, profile_row.get("display_name", "OneLiner"), profile_row.get("long_term_goal", ""), profile_row.get("notes", ""), profile_row.get("default_platform", ""), profile_row.get("config_json", "{}"), summary, reason.strip(), source_type, rollback_from_version_id, actor_user_id, now(), ), ) row = legacy.db.fetch_one("SELECT * FROM oneliner_profile_versions WHERE id = ?", (version_id,)) assert row is not None return _oneliner_profile_version_payload(row) def _ensure_oneliner_profile_version_seed(profile_row: dict[str, Any], *, actor_user_id: str = "") -> dict[str, Any]: current_version = _current_oneliner_profile_version_row(profile_row) if current_version: payload = _oneliner_profile_version_payload(current_version) assert payload is not None return payload payload = _create_oneliner_profile_version( profile_row, actor_user_id=actor_user_id or profile_row.get("user_id", ""), source_type="system_seed", reason="初始化 OneLiner 主配置", ) _log_oneliner_profile_audit( profile_id=profile_row["id"], version_id=payload["id"], actor_user_id=actor_user_id or profile_row.get("user_id", ""), action_key="seed-oneliner-profile", summary="初始化 OneLiner 主配置版本", details={"project_id": profile_row.get("project_id", "")}, ) return payload def _oneliner_profile_bundle(row: dict[str, Any], *, account: dict[str, Any] | None = None) -> dict[str, Any]: _ensure_oneliner_profile_version_seed(row, actor_user_id=(account or {}).get("id", "")) payload = _profile_payload(row, account=account) current_version = _oneliner_profile_version_payload(_current_oneliner_profile_version_row(row)) versions = _list_oneliner_profile_versions(row) audits = _list_oneliner_profile_audits(row) payload.update( { "current_version": current_version, "versions": {"items": versions, "count": len(versions)}, "audits": {"items": audits, "count": len(audits)}, } ) return payload def _summarize_platform_agent_profile(row: dict[str, Any] | None) -> str: data = row or {} def _clip(value: str, limit: int) -> str: text = str(value or "").strip() if len(text) <= limit: return text return f"{text[: max(limit - 1, 0)].rstrip()}…" parts: list[str] = [] name = str(data.get("name") or "").strip() if name: parts.append(name) mission = str(data.get("mission") or "").strip() if mission: parts.append(_clip(mission, 36)) notes = str(data.get("notes") or "").strip() if notes: parts.append(f"备注 {_clip(notes, 32)}") return ",".join(parts[:4]) def _platform_agent_profile_version_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None assistant = None if row.get("assistant_id"): assistant_row = legacy.db.fetch_one("SELECT * FROM assistants WHERE id = ?", (row["assistant_id"],)) if assistant_row: assistant = legacy.assistant_payload(assistant_row) return { "id": row["id"], "profile_id": row.get("profile_id", ""), "user_id": row.get("user_id", ""), "project_id": row.get("project_id", ""), "platform": row.get("platform", ""), "assistant_id": row.get("assistant_id", ""), "version_no": int(row.get("version_no") or 0), "name": row.get("name", ""), "mission": row.get("mission", ""), "notes": row.get("notes", ""), "status": row.get("status", "active"), "config": _parse_json(row.get("config_json"), {}), "summary": row.get("summary", ""), "reason": row.get("reason", ""), "source_type": row.get("source_type", ""), "rollback_from_version_id": row.get("rollback_from_version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "assistant": assistant, "created_at": row.get("created_at", ""), } def _platform_agent_profile_audit_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None version_row = legacy.db.fetch_one("SELECT * FROM platform_agent_profile_versions WHERE id = ?", (row.get("version_id", ""),)) if row.get("version_id") else None return { "id": row["id"], "profile_id": row.get("profile_id", ""), "version_id": row.get("version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "action_key": row.get("action_key", ""), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "version": _platform_agent_profile_version_payload(version_row), "created_at": row.get("created_at", ""), } def _list_platform_agent_profile_versions(profile_row: dict[str, Any] | None) -> list[dict[str, Any]]: if not profile_row: return [] rows = legacy.db.fetch_all( """ SELECT * FROM platform_agent_profile_versions WHERE profile_id = ? ORDER BY version_no DESC, created_at DESC """, (profile_row["id"],), ) return [_platform_agent_profile_version_payload(row) for row in rows if row] def _list_platform_agent_profile_audits(profile_row: dict[str, Any] | None, *, limit: int = 12) -> list[dict[str, Any]]: if not profile_row: return [] rows = legacy.db.fetch_all( """ SELECT * FROM platform_agent_profile_audit_logs WHERE profile_id = ? ORDER BY created_at DESC LIMIT ? """, (profile_row["id"], limit), ) return [_platform_agent_profile_audit_payload(row) for row in rows if row] def _current_platform_agent_profile_version_row(profile_row: dict[str, Any] | None) -> dict[str, Any] | None: if not profile_row: return None return legacy.db.fetch_one( """ SELECT * FROM platform_agent_profile_versions WHERE profile_id = ? ORDER BY version_no DESC, created_at DESC LIMIT 1 """, (profile_row["id"],), ) def _log_platform_agent_profile_audit( *, profile_id: str, version_id: str, actor_user_id: str, action_key: str, summary: str, details: dict[str, Any] | None = None, ) -> dict[str, Any]: audit_id = make_id("plat_agent_audit") legacy.db.execute( """ INSERT INTO platform_agent_profile_audit_logs ( id, profile_id, version_id, actor_user_id, action_key, summary, details_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, ( audit_id, profile_id, version_id, actor_user_id, action_key, summary, _dump(details or {}), now(), ), ) row = legacy.db.fetch_one("SELECT * FROM platform_agent_profile_audit_logs WHERE id = ?", (audit_id,)) assert row is not None return _platform_agent_profile_audit_payload(row) def _create_platform_agent_profile_version( profile_row: dict[str, Any], *, actor_user_id: str, source_type: str, reason: str, rollback_from_version_id: str = "", ) -> dict[str, Any]: current = legacy.db.fetch_one( "SELECT COALESCE(MAX(version_no), 0) AS max_version FROM platform_agent_profile_versions WHERE profile_id = ?", (profile_row["id"],), ) version_no = int((current or {}).get("max_version") or 0) + 1 version_id = make_id("plat_agent_ver") summary = _summarize_platform_agent_profile(profile_row) version_params = ( version_id, profile_row["id"], profile_row.get("user_id", ""), profile_row.get("project_id", ""), profile_row.get("platform", ""), profile_row.get("assistant_id", ""), version_no, profile_row.get("name", ""), profile_row.get("mission", ""), profile_row.get("notes", ""), profile_row.get("status", "active"), profile_row.get("config_json", "{}"), summary, reason.strip(), source_type, rollback_from_version_id, actor_user_id, now(), ) insert_sql = """ INSERT INTO platform_agent_profile_versions ( id, profile_id, user_id, project_id, platform, assistant_id, version_no, name, mission, notes, status, config_json, summary, reason, source_type, rollback_from_version_id, actor_user_id, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """ if profile_row.get("assistant_id"): legacy.db.execute(insert_sql, version_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(insert_sql, version_params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM platform_agent_profile_versions WHERE id = ?", (version_id,)) assert row is not None return _platform_agent_profile_version_payload(row) def _ensure_platform_agent_profile_version_seed(profile_row: dict[str, Any], *, actor_user_id: str = "") -> dict[str, Any]: current_version = _current_platform_agent_profile_version_row(profile_row) if current_version: payload = _platform_agent_profile_version_payload(current_version) assert payload is not None return payload payload = _create_platform_agent_profile_version( profile_row, actor_user_id=actor_user_id or profile_row.get("user_id", ""), source_type="system_seed", reason="初始化平台 Agent 配置", ) _log_platform_agent_profile_audit( profile_id=profile_row["id"], version_id=payload["id"], actor_user_id=actor_user_id or profile_row.get("user_id", ""), action_key="seed-platform-agent-profile", summary="初始化平台 Agent 配置版本", details={"project_id": profile_row.get("project_id", ""), "platform": profile_row.get("platform", "")}, ) return payload def _oneliner_profile_runtime_snapshot(row: dict[str, Any], *, account: dict[str, Any] | None = None) -> dict[str, Any]: bundle = _oneliner_profile_bundle(row, account=account) return { "id": str(bundle.get("id") or "").strip(), "assistant_id": str(bundle.get("assistant_id") or "").strip(), "display_name": str(bundle.get("display_name") or "").strip(), "long_term_goal": str(bundle.get("long_term_goal") or "").strip(), "default_platform": str(bundle.get("default_platform") or "").strip(), "notes": str(bundle.get("notes") or "").strip(), "summary": str(bundle.get("summary") or "").strip(), "current_version": { "id": str((bundle.get("current_version") or {}).get("id") or "").strip(), "version_no": int((bundle.get("current_version") or {}).get("version_no") or 0), "title": str((bundle.get("current_version") or {}).get("title") or "").strip(), "summary": str((bundle.get("current_version") or {}).get("summary") or "").strip(), "reason": str((bundle.get("current_version") or {}).get("reason") or "").strip(), "created_at": str((bundle.get("current_version") or {}).get("created_at") or "").strip(), }, } def _profile_payload(row: dict[str, Any], *, account: dict[str, Any] | None = None) -> dict[str, Any]: assistant = None if row.get("assistant_id"): assistant_row = legacy.db.fetch_one("SELECT * FROM assistants WHERE id = ?", (row["assistant_id"],)) if assistant_row and (not account or assistant_row.get("user_id") == account["id"]): assistant = legacy.assistant_payload(assistant_row) return { "id": row["id"], "user_id": row["user_id"], "project_id": row.get("project_id", ""), "assistant_id": row.get("assistant_id", ""), "display_name": row.get("display_name", "OneLiner"), "long_term_goal": row.get("long_term_goal", ""), "notes": row.get("notes", ""), "default_platform": row.get("default_platform", ""), "config": _parse_json(row.get("config_json"), {}), "assistant": assistant, "created_at": row["created_at"], "updated_at": row["updated_at"], } def _ensure_oneliner_profile(account: dict[str, Any], project_id: str = "") -> dict[str, Any]: row = _fetch_profile_row(account, project_id) if row: return row assistant_id = "" if project_id: assistant_row = legacy.db.fetch_one( "SELECT * FROM assistants WHERE user_id = ? AND (project_id = ? OR project_id = '') ORDER BY created_at ASC LIMIT 1", (account["id"], project_id), ) else: assistant_row = legacy.db.fetch_one( "SELECT * FROM assistants WHERE user_id = ? ORDER BY created_at ASC LIMIT 1", (account["id"],), ) if assistant_row: assistant_id = assistant_row["id"] profile_id = make_id("oneliner") created_at = now() default_platform = "douyin" insert_sql = """ INSERT INTO oneliner_profiles ( id, user_id, project_id, assistant_id, display_name, long_term_goal, notes, default_platform, config_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """ insert_params = ( profile_id, account["id"], project_id, assistant_id, "OneLiner", "", "", default_platform, _dump({"chat_only_for_unreleased_ui": True}), created_at, created_at, ) if assistant_id: legacy.db.execute(insert_sql, insert_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(insert_sql, insert_params) conn.execute("PRAGMA foreign_keys=ON") return legacy.db.fetch_one("SELECT * FROM oneliner_profiles WHERE id = ?", (profile_id,)) def _list_platform_profiles(account: dict[str, Any], project_id: str = "") -> list[dict[str, Any]]: rows = legacy.db.fetch_all( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? ORDER BY platform ASC", (account["id"], project_id), ) mapping = {row["platform"]: row for row in rows} results: list[dict[str, Any]] = [] for platform in sorted(legacy.DOMESTIC_PLATFORMS): row = mapping.get(platform) payload = _platform_agent_payload(account, row, platform=platform, project_id=project_id) results.append(payload) return results def _platform_agent_payload( account: dict[str, Any], row: dict[str, Any] | None, *, platform: str, project_id: str = "", ) -> dict[str, Any]: assistant = None if row and row.get("assistant_id"): assistant_row = legacy.db.fetch_one("SELECT * FROM assistants WHERE id = ?", (row["assistant_id"],)) if assistant_row and assistant_row.get("user_id") == account["id"]: assistant = legacy.assistant_payload(assistant_row) memory_count = legacy.db.fetch_one( """ SELECT COUNT(*) AS count FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? """, (account["id"], project_id, platform), )["count"] skill_count = legacy.db.fetch_one( """ SELECT COUNT(*) AS count FROM agent_skills WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? """, (account["id"], project_id, platform), )["count"] recent_memory_row = legacy.db.fetch_one( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY updated_at DESC LIMIT 1 """, (account["id"], project_id, platform), ) recent_skill_row = legacy.db.fetch_one( """ SELECT * FROM agent_skills WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY CASE WHEN status = 'validated' THEN 0 WHEN status = 'draft' THEN 1 ELSE 2 END, updated_at DESC LIMIT 1 """, (account["id"], project_id, platform), ) readiness_items = [ bool(row and row.get("status") == "active"), bool(assistant), bool(memory_count), bool(skill_count), ] readiness_score = int(sum(1 for item in readiness_items if item) * 25) if readiness_score >= 100: readiness_label = "就绪" elif readiness_score >= 50: readiness_label = "可用" else: readiness_label = "待补全" def build_recent_execution_payload(base_payload: dict[str, Any], run_row: dict[str, Any] | None) -> dict[str, Any]: if not run_row: return base_payload latest_result = _parse_json(run_row.get("result_json"), {}) latest_governance = _parse_json(run_row.get("governance_json"), {}) latest_plan = _parse_json(run_row.get("plan_json"), {}) execution_card = (latest_result.get("execution_card") or {}) if isinstance(latest_result, dict) else {} result_sections = (latest_result.get("result_sections") or {}) if isinstance(latest_result, dict) else {} recommended_action = {} if isinstance(latest_result, dict): recommended_action = latest_result.get("recommended_action") or latest_result.get("recommended_preview_action") or {} oneliner_profile_version = ( execution_card.get("oneliner_profile_version") or latest_governance.get("oneliner_profile_version") or (latest_governance.get("oneliner_profile") or {}).get("current_version") or {} ) platform_profile_version = ( execution_card.get("platform_agent_profile") or ((latest_governance.get("platform_agent_profile") or {}).get("current_version") or {}) ) return { **base_payload, "title": str(run_row.get("title") or latest_plan.get("goal") or "").strip(), "goal": str(latest_plan.get("goal") or run_row.get("title") or "").strip(), "platform_scope": str(run_row.get("platform_scope") or "").strip(), "delivery_mode": str(run_row.get("delivery_mode") or "").strip(), "active_executor_key": str(run_row.get("active_executor_key") or "").strip(), "source_action_key": str(run_row.get("source_action_key") or "").strip(), "oneliner_profile_version_id": str(oneliner_profile_version.get("version_id") or oneliner_profile_version.get("id") or "").strip(), "platform_agent_profile_version_id": str(platform_profile_version.get("version_id") or platform_profile_version.get("id") or "").strip(), "recommended_action": { "action": str(recommended_action.get("action") or "").strip(), "screen": str(recommended_action.get("screen") or "").strip(), "label": str(recommended_action.get("label") or "").strip(), "summary": str(recommended_action.get("summary") or "").strip(), }, "workstream_key": str(result_sections.get("workstream_key") or "").strip(), "workstream_label": str(result_sections.get("workstream_label") or "").strip(), } recent_execution = None current_version = None if row: _ensure_platform_agent_profile_version_seed(row, actor_user_id=account.get("id", "")) current_version = _platform_agent_profile_version_payload(_current_platform_agent_profile_version_row(row)) if row and str(row.get("last_run_id") or "").strip(): recent_execution = build_recent_execution_payload({ "run_id": str(row.get("last_run_id") or "").strip(), "run_status": str(row.get("last_run_status") or "").strip(), "used_at": str(row.get("last_used_at") or "").strip(), "intent_key": str(row.get("last_intent_key") or "").strip(), "intent_label": INTENT_LABELS.get(str(row.get("last_intent_key") or "").strip() or "custom", "主 Agent 任务"), "oneliner_profile_version_no": int(row.get("last_oneliner_profile_version_no") or 0), "platform_agent_profile_version_no": int(row.get("last_platform_profile_version_no") or 0), "summary": str(row.get("last_execution_summary") or "").strip(), "source_screen": str(row.get("last_source_screen") or "").strip(), }, legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (str(row.get("last_run_id") or "").strip(),))) if recent_execution is None and str(project_id or "").strip() and str(platform or "").strip(): latest_run_row = legacy.db.fetch_one( """ SELECT * FROM agent_runs WHERE user_id = ? AND project_id = ? AND platform = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"], project_id, platform), ) if latest_run_row: latest_result = _parse_json(latest_run_row.get("result_json"), {}) latest_governance = _parse_json(latest_run_row.get("governance_json"), {}) latest_profile_version = ( ((latest_result.get("execution_card") or {}).get("oneliner_profile_version")) or latest_governance.get("oneliner_profile_version") or {} ) recent_execution = build_recent_execution_payload({ "run_id": str(latest_run_row.get("id") or "").strip(), "run_status": str(latest_run_row.get("run_status") or "").strip(), "used_at": str(latest_run_row.get("finished_at") or latest_run_row.get("updated_at") or "").strip(), "intent_key": str(latest_run_row.get("intent_key") or "").strip(), "intent_label": INTENT_LABELS.get(str(latest_run_row.get("intent_key") or "").strip() or "custom", "主 Agent 任务"), "oneliner_profile_version_no": int(latest_profile_version.get("version_no") or 0), "platform_agent_profile_version_no": int( (((latest_result.get("execution_card") or {}).get("platform_agent_profile") or {}).get("version_no")) or (((latest_governance.get("platform_agent_profile") or {}).get("current_version") or {}).get("version_no")) or 0 ), "summary": str(latest_run_row.get("status_summary") or "").strip(), "source_screen": str(latest_run_row.get("source_screen") or "").strip(), }, latest_run_row) return { "id": row["id"] if row else "", "user_id": account["id"], "project_id": project_id, "platform": platform, "platform_label": legacy.platform_label(platform), "assistant_id": row.get("assistant_id", "") if row else "", "name": row.get("name", f"{legacy.platform_label(platform)} Agent") if row else f"{legacy.platform_label(platform)} Agent", "mission": row.get("mission", "") if row else "", "notes": row.get("notes", "") if row else "", "status": row.get("status", "draft") if row else "draft", "config": _parse_json((row or {}).get("config_json"), {}), "memory_count": memory_count, "skill_count": skill_count, "recent_memory": _memory_payload(recent_memory_row) if recent_memory_row else None, "recent_skill": _skill_payload(recent_skill_row) if recent_skill_row else None, "recent_execution": recent_execution, "readiness_score": readiness_score, "readiness_label": readiness_label, "assistant": assistant, "current_version": current_version, "created_at": (row or {}).get("created_at", ""), "updated_at": (row or {}).get("updated_at", ""), } def _platform_agent_runtime_snapshot( account: dict[str, Any], row: dict[str, Any] | None, *, platform: str, project_id: str = "", ) -> dict[str, Any]: payload = _platform_agent_payload(account, row, platform=platform, project_id=project_id) assistant = payload.get("assistant") or {} recent_memory = payload.get("recent_memory") or {} recent_skill = payload.get("recent_skill") or {} return { "id": str(payload.get("id") or "").strip(), "platform": str(payload.get("platform") or platform or "").strip(), "platform_label": str(payload.get("platform_label") or legacy.platform_label(platform) or "").strip(), "assistant_id": str(payload.get("assistant_id") or "").strip(), "assistant_name": str((assistant or {}).get("name") or "").strip(), "name": str(payload.get("name") or "").strip(), "mission": str(payload.get("mission") or "").strip(), "notes": str(payload.get("notes") or "").strip(), "status": str(payload.get("status") or "").strip(), "memory_count": int(payload.get("memory_count") or 0), "skill_count": int(payload.get("skill_count") or 0), "readiness_score": int(payload.get("readiness_score") or 0), "readiness_label": str(payload.get("readiness_label") or "").strip(), "recent_memory_title": str(recent_memory.get("title") or "").strip(), "recent_skill_title": str(recent_skill.get("title") or "").strip(), "recent_execution": payload.get("recent_execution") or {}, "current_version": payload.get("current_version") or {}, } def _record_platform_agent_execution_feedback( account_id: str, *, project_id: str, platform: str, run_id: str, run_status: str, intent_key: str, source_screen: str, oneliner_profile_version_no: int, platform_agent_profile_version_no: int, execution_summary: str, ) -> None: normalized_platform = _safe_platform(platform, fallback="") if str(platform or "").strip() else "" if not normalized_platform or not str(project_id or "").strip() or not str(run_id or "").strip(): return legacy.db.execute( """ UPDATE platform_agent_profiles SET last_run_id = ?, last_run_status = ?, last_used_at = ?, last_intent_key = ?, last_oneliner_profile_version_no = ?, last_platform_profile_version_no = ?, last_execution_summary = ?, last_source_screen = ?, updated_at = ? WHERE user_id = ? AND project_id = ? AND platform = ? """, ( str(run_id).strip(), str(run_status or "").strip(), now(), str(intent_key or "custom").strip() or "custom", int(oneliner_profile_version_no or 0), int(platform_agent_profile_version_no or 0), str(execution_summary or "").strip(), str(source_screen or "").strip(), now(), account_id, project_id, normalized_platform, ), ) def _memory_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "user_id": row["user_id"], "project_id": row.get("project_id", ""), "agent_scope": row.get("agent_scope", ""), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "subject_type": row.get("subject_type", ""), "subject_id": row.get("subject_id", ""), "memory_key": row.get("memory_key", ""), "title": row.get("title", ""), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "confidence": float(row.get("confidence") or 0), "last_validated_at": row.get("last_validated_at", ""), "created_at": row["created_at"], "updated_at": row["updated_at"], } def _skill_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "user_id": row["user_id"], "project_id": row.get("project_id", ""), "agent_scope": row.get("agent_scope", ""), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "parent_skill_id": row.get("parent_skill_id", ""), "skill_key": row.get("skill_key", ""), "name": row.get("name", ""), "status": row.get("status", "draft"), "method": _parse_json(row.get("method_json"), {}), "test_spec": _parse_json(row.get("test_spec_json"), {}), "last_result": _parse_json(row.get("last_result_json"), {}), "success_count": int(row.get("success_count") or 0), "failure_count": int(row.get("failure_count") or 0), "last_score": float(row.get("last_score") or 0), "last_validated_at": row.get("last_validated_at", ""), "created_at": row["created_at"], "updated_at": row["updated_at"], } def _session_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "user_id": row["user_id"], "project_id": row.get("project_id", ""), "profile_id": row.get("profile_id", ""), "title": row.get("title", ""), "status": row.get("status", "active"), "preferred_platform": row.get("preferred_platform", ""), "last_platform": row.get("last_platform", ""), "last_intent_key": row.get("last_intent_key", ""), "last_message_at": row.get("last_message_at", ""), "created_at": row["created_at"], "updated_at": row["updated_at"], } def _message_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "session_id": row["session_id"], "user_id": row["user_id"], "role": row.get("role", "user"), "content": row.get("content", ""), "plan": _parse_json(row.get("plan_json"), {}), "result": _parse_json(row.get("result_json"), {}), "created_at": row["created_at"], } def _agent_run_event_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "run_id": row.get("run_id", ""), "event_type": row.get("event_type", ""), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "created_at": row.get("created_at", ""), } def _list_agent_run_events(run_id: str) -> list[dict[str, Any]]: rows = legacy.db.fetch_all( """ SELECT * FROM agent_run_events WHERE run_id = ? ORDER BY created_at ASC """, (run_id,), ) return [_agent_run_event_payload(row) for row in rows] def _agent_run_payload(row: dict[str, Any], *, include_events: bool = True) -> dict[str, Any]: plan = _parse_json(row.get("plan_json"), {}) result = _parse_json(row.get("result_json"), {}) recommended_preview_action = result.get("recommended_action") if isinstance(result, dict) else {} if not recommended_preview_action: recommended_preview_action = _build_agent_run_recommended_action(row, plan) payload = { "id": row["id"], "user_id": row.get("user_id", ""), "project_id": row.get("project_id", ""), "session_id": row.get("session_id", ""), "source_screen": row.get("source_screen", ""), "source_action_key": row.get("source_action_key", ""), "title": row.get("title", ""), "summary": row.get("summary", ""), "intent_key": row.get("intent_key", "custom"), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "platform_scope": row.get("platform_scope", "single_platform"), "delivery_mode": row.get("delivery_mode", "hybrid"), "run_status": row.get("run_status", "needs_confirmation"), "scheduling_mode": row.get("scheduling_mode", "queued"), "active_executor_key": row.get("active_executor_key", "main_agent"), "plan": plan, "governance": _parse_json(row.get("governance_json"), {}), "result": result, "recommended_preview_action": recommended_preview_action, "status_summary": row.get("status_summary", ""), "needs_user_input": bool(row.get("needs_user_input")), "blocked_reason": row.get("blocked_reason", ""), "active_admin_override_notice": _parse_json(row.get("active_admin_override_notice_json"), {}), "created_at": row.get("created_at", ""), "updated_at": row.get("updated_at", ""), "started_at": row.get("started_at", ""), "finished_at": row.get("finished_at", ""), } if include_events: payload["events"] = _list_agent_run_events(row["id"]) return payload def _incident_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "tenant_user_id": row.get("tenant_user_id", ""), "tenant_project_id": row.get("tenant_project_id", ""), "source_type": row.get("source_type", ""), "source_id": row.get("source_id", ""), "severity": row.get("severity", "warn"), "title": row.get("title", ""), "summary": row.get("summary", ""), "payload": _parse_json(row.get("payload_json"), {}), "status": row.get("status", "open"), "assigned_to": row.get("assigned_to", ""), "reviewed_by": row.get("reviewed_by", ""), "review_notes": row.get("review_notes", ""), "created_at": row["created_at"], "updated_at": row["updated_at"], } def _admin_audit_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "actor_user_id": row.get("actor_user_id", ""), "incident_id": row.get("incident_id", ""), "action_key": row.get("action_key", ""), "status": row.get("status", "recorded"), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "created_at": row.get("created_at", ""), } def _action_definition_payload(row: dict[str, Any] | None, *, fallback_key: str = "") -> dict[str, Any]: fallback = ACTION_REGISTRY_DEFAULTS.get(fallback_key or "", {}) data = row or {} action_key = data.get("action_key") or fallback_key return { "id": data.get("id", ""), "user_id": data.get("user_id", ""), "project_id": data.get("project_id", ""), "action_key": action_key, "handler_key": data.get("handler_key") or fallback.get("handler_key") or action_key, "label": data.get("label") or fallback.get("label") or action_key, "description": data.get("description") or fallback.get("description") or "", "category": data.get("category") or fallback.get("category") or "custom", "status": data.get("status") or fallback.get("status") or "enabled", "admin_only": _bool_flag(data.get("admin_only", fallback.get("admin_only", False))), "requires_platform": _bool_flag(data.get("requires_platform", fallback.get("requires_platform", False))), "config": _parse_json(data.get("config_json"), fallback.get("config") or {}), "created_at": data.get("created_at", ""), "updated_at": data.get("updated_at", ""), "source": "override" if row else "default", } def _list_action_registry(account: dict[str, Any], *, project_id: str) -> list[dict[str, Any]]: rows = legacy.db.fetch_all( """ SELECT * FROM oneliner_action_definitions WHERE user_id = ? AND project_id = ? ORDER BY category ASC, action_key ASC """, (account["id"], project_id), ) row_map = {row["action_key"]: row for row in rows} items = [] for action_key in sorted(ACTION_REGISTRY_DEFAULTS.keys()): items.append(_action_definition_payload(row_map.get(action_key), fallback_key=action_key)) for action_key, row in row_map.items(): if action_key in ACTION_REGISTRY_DEFAULTS: continue items.append(_action_definition_payload(row, fallback_key=action_key)) return items def _get_action_definition(account: dict[str, Any], *, project_id: str, action_key: str) -> dict[str, Any] | None: normalized_key = str(action_key or "").strip() if not normalized_key: return None row = legacy.db.fetch_one( """ SELECT * FROM oneliner_action_definitions WHERE user_id = ? AND project_id = ? AND action_key = ? """, (account["id"], project_id, normalized_key), ) if row: return _action_definition_payload(row, fallback_key=normalized_key) if normalized_key in ACTION_REGISTRY_DEFAULTS: return _action_definition_payload(None, fallback_key=normalized_key) return None def _decorate_oneliner_action(account: dict[str, Any], *, project_id: str, action: dict[str, Any]) -> dict[str, Any]: cloned = dict(action or {}) executor_key = str(cloned.get("executor_key") or "").strip() if not executor_key: return cloned definition = _get_action_definition(account, project_id=project_id, action_key=executor_key) if not definition: cloned["disabled_reason"] = "当前租户还没有接入这条动作。" return cloned cloned["executor_label"] = definition.get("label") or cloned.get("label") or executor_key if cloned.get("kind") == "api_action" and not cloned.get("label"): cloned["label"] = definition.get("label") or executor_key if definition.get("status") != "enabled": cloned["disabled_reason"] = "当前租户已停用这条动作。" elif definition.get("admin_only") and account.get("role") != "super_admin": cloned["disabled_reason"] = "只有平台管理者才能执行这条动作。" elif definition.get("requires_platform") and not cloned.get("platform"): cloned["disabled_reason"] = "这条动作需要先选定平台。" return cloned def _upsert_action_definition( account: dict[str, Any], *, project_id: str, action_key: str, request: OneLinerActionDefinitionRequest, ) -> dict[str, Any]: normalized_key = str(action_key or "").strip() if not normalized_key: raise HTTPException(status_code=400, detail="Action key is required") fallback = ACTION_REGISTRY_DEFAULTS.get(normalized_key) existing = legacy.db.fetch_one( """ SELECT * FROM oneliner_action_definitions WHERE user_id = ? AND project_id = ? AND action_key = ? """, (account["id"], project_id, normalized_key), ) if not existing and not fallback: raise HTTPException(status_code=404, detail="Action definition not found") timestamp = now() handler_key = (existing or {}).get("handler_key") or (fallback or {}).get("handler_key") or normalized_key next_admin_only = (fallback or {}).get("admin_only", False) next_requires_platform = (fallback or {}).get("requires_platform", False) if account.get("role") == "super_admin": if request.admin_only is not None: next_admin_only = bool(request.admin_only) if request.requires_platform is not None: next_requires_platform = bool(request.requires_platform) if existing: legacy.db.execute( """ UPDATE oneliner_action_definitions SET label = ?, description = ?, category = ?, status = ?, admin_only = ?, requires_platform = ?, config_json = ?, updated_at = ? WHERE id = ? """, ( request.label.strip() or existing.get("label") or (fallback or {}).get("label") or normalized_key, request.description.strip() or existing.get("description") or (fallback or {}).get("description") or "", request.category.strip() or existing.get("category") or (fallback or {}).get("category") or "custom", request.status.strip() or existing.get("status") or (fallback or {}).get("status") or "enabled", 1 if next_admin_only else 0, 1 if next_requires_platform else 0, _dump(request.config or _parse_json(existing.get("config_json"), (fallback or {}).get("config") or {})), timestamp, existing["id"], ), ) row = legacy.db.fetch_one("SELECT * FROM oneliner_action_definitions WHERE id = ?", (existing["id"],)) else: definition_id = make_id("oline_action") legacy.db.execute( """ INSERT INTO oneliner_action_definitions ( id, user_id, project_id, action_key, handler_key, label, description, category, status, admin_only, requires_platform, config_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( definition_id, account["id"], project_id, normalized_key, handler_key, request.label.strip() or (fallback or {}).get("label") or normalized_key, request.description.strip() or (fallback or {}).get("description") or "", request.category.strip() or (fallback or {}).get("category") or "custom", request.status.strip() or (fallback or {}).get("status") or "enabled", 1 if next_admin_only else 0, 1 if next_requires_platform else 0, _dump(request.config or (fallback or {}).get("config") or {}), timestamp, timestamp, ), ) row = legacy.db.fetch_one("SELECT * FROM oneliner_action_definitions WHERE id = ?", (definition_id,)) return _action_definition_payload(row, fallback_key=normalized_key) def _skill_version_payload(row: dict[str, Any]) -> dict[str, Any]: snapshot = _parse_json(row.get("snapshot_json"), {}) return { "id": row["id"], "skill_id": row.get("skill_id", ""), "user_id": row.get("user_id", ""), "project_id": row.get("project_id", ""), "agent_scope": row.get("agent_scope", ""), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "version_no": int(row.get("version_no") or 0), "snapshot_reason": row.get("snapshot_reason", "updated"), "snapshot": snapshot, "actor_user_id": row.get("actor_user_id", ""), "created_at": row.get("created_at", ""), } def _snapshot_skill_version( skill_row: dict[str, Any], *, actor_user_id: str, reason: str, metadata: dict[str, Any] | None = None, ) -> dict[str, Any]: current = legacy.db.fetch_one( "SELECT COALESCE(MAX(version_no), 0) AS max_version FROM agent_skill_versions WHERE skill_id = ?", (skill_row["id"],), ) next_version = int((current or {}).get("max_version") or 0) + 1 version_id = make_id("skill_ver") snapshot = { "skill": _skill_payload(skill_row), "metadata": metadata or {}, } legacy.db.execute( """ INSERT INTO agent_skill_versions ( id, skill_id, user_id, project_id, agent_scope, platform, version_no, snapshot_reason, snapshot_json, actor_user_id, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( version_id, skill_row["id"], skill_row.get("user_id", ""), skill_row.get("project_id", ""), skill_row.get("agent_scope", ""), skill_row.get("platform", ""), next_version, reason, _dump(snapshot), actor_user_id, now(), ), ) row = legacy.db.fetch_one("SELECT * FROM agent_skill_versions WHERE id = ?", (version_id,)) return _skill_version_payload(row) def _normalize_policy_platform(platform: str | None) -> str: if not str(platform or "").strip(): return "" return _safe_platform(platform, fallback="") def _deep_merge_policy(base: Any, override: Any) -> Any: if not isinstance(base, dict) or not isinstance(override, dict): return override if override is not None else base merged = {key: value for key, value in base.items()} for key, value in override.items(): if key in merged and isinstance(merged[key], dict) and isinstance(value, dict): merged[key] = _deep_merge_policy(merged[key], value) else: merged[key] = value return merged def _policy_scope_default_title(scope_kind: str, *, platform: str = "") -> str: if scope_kind == "system_main": return "系统主 Agent 策略" if scope_kind == "system_platform": return f"{legacy.platform_label(platform)} 系统平台策略" if scope_kind == "user_global": return "用户全局策略" if scope_kind == "user_platform": return f"{legacy.platform_label(platform)} 用户平台策略" if scope_kind == "admin_override": return "管理员覆盖策略" return "Agent 策略" def _policy_scope_row( *, scope_kind: str, subject_user_id: str = "", subject_project_id: str = "", platform: str = "", ) -> dict[str, Any] | None: return legacy.db.fetch_one( """ SELECT * FROM agent_policy_scopes WHERE scope_kind = ? AND subject_user_id = ? AND subject_project_id = ? AND platform = ? """, (scope_kind, subject_user_id, subject_project_id, platform), ) def _policy_scope_payload(row: dict[str, Any] | None, *, fallback_kind: str = "", fallback_platform: str = "", fallback_user_id: str = "", fallback_project_id: str = "") -> dict[str, Any]: data = row or {} scope_kind = data.get("scope_kind") or fallback_kind platform = data.get("platform") or fallback_platform return { "id": data.get("id", ""), "scope_kind": scope_kind, "subject_user_id": data.get("subject_user_id", fallback_user_id), "subject_project_id": data.get("subject_project_id", fallback_project_id), "platform": platform, "platform_label": legacy.platform_label(platform) if platform else "", "status": data.get("status", "active"), "title": data.get("title") or _policy_scope_default_title(scope_kind, platform=platform), "summary": data.get("summary", ""), "current_version_id": data.get("current_version_id", ""), "created_at": data.get("created_at", ""), "updated_at": data.get("updated_at", ""), } def _policy_version_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None return { "id": row["id"], "scope_id": row.get("scope_id", ""), "scope_kind": row.get("scope_kind", ""), "subject_user_id": row.get("subject_user_id", ""), "subject_project_id": row.get("subject_project_id", ""), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "version_no": int(row.get("version_no") or 0), "title": row.get("title", ""), "summary": row.get("summary", ""), "policy": _parse_json(row.get("policy_json"), {}), "reason": row.get("reason", ""), "source_type": row.get("source_type", ""), "rollback_from_version_id": row.get("rollback_from_version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "created_at": row.get("created_at", ""), } def _policy_version_public_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None return { "id": row["id"], "scope_id": row.get("scope_id", ""), "scope_kind": row.get("scope_kind", ""), "subject_user_id": row.get("subject_user_id", ""), "subject_project_id": row.get("subject_project_id", ""), "platform": row.get("platform", ""), "platform_label": legacy.platform_label(row.get("platform", "")) if row.get("platform") else "", "version_no": int(row.get("version_no") or 0), "title": row.get("title", ""), "summary": row.get("summary", ""), "source_type": row.get("source_type", ""), "created_at": row.get("created_at", ""), } def _policy_effectivity_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None return { "id": row["id"], "scope_id": row.get("scope_id", ""), "version_id": row.get("version_id", ""), "effect_mode": row.get("effect_mode", "ongoing"), "starts_at": row.get("starts_at", ""), "ends_at": row.get("ends_at", ""), "status": row.get("status", "active"), "config": _parse_json(row.get("config_json"), {}), "created_at": row.get("created_at", ""), "updated_at": row.get("updated_at", ""), } def _policy_audit_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None return { "id": row["id"], "scope_id": row.get("scope_id", ""), "version_id": row.get("version_id", ""), "actor_user_id": row.get("actor_user_id", ""), "action_key": row.get("action_key", ""), "summary": row.get("summary", ""), "details": _parse_json(row.get("details_json"), {}), "created_at": row.get("created_at", ""), } def _policy_public_audit_details(details: dict[str, Any] | None) -> dict[str, Any]: data = details or {} public_keys = {"project_id", "platform", "target_project_id"} return {key: data.get(key) for key in public_keys if data.get(key) not in (None, "")} def _ensure_policy_scope( *, scope_kind: str, subject_user_id: str = "", subject_project_id: str = "", platform: str = "", title: str = "", summary: str = "", ) -> dict[str, Any]: normalized_platform = _normalize_policy_platform(platform) existing = _policy_scope_row( scope_kind=scope_kind, subject_user_id=subject_user_id, subject_project_id=subject_project_id, platform=normalized_platform, ) if existing: return existing scope_id = make_id("policy_scope") timestamp = now() legacy.db.execute( """ INSERT INTO agent_policy_scopes ( id, scope_kind, subject_user_id, subject_project_id, platform, status, title, summary, current_version_id, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, '', ?, ?) """, ( scope_id, scope_kind, subject_user_id, subject_project_id, normalized_platform, title.strip() or _policy_scope_default_title(scope_kind, platform=normalized_platform), summary.strip(), timestamp, timestamp, ), ) row = legacy.db.fetch_one("SELECT * FROM agent_policy_scopes WHERE id = ?", (scope_id,)) assert row is not None return row def _policy_effectivity_is_active( effectivity_row: dict[str, Any] | None, *, current_time: datetime | None = None, ) -> bool: if not effectivity_row: return True status = str(effectivity_row.get("status") or "active").strip().lower() if status and status != "active": return False effect_mode = str(effectivity_row.get("effect_mode") or "ongoing").strip().lower() starts_at = _parse_policy_datetime(effectivity_row.get("starts_at")) ends_at = _parse_policy_datetime(effectivity_row.get("ends_at")) reference_time = current_time or datetime.now(timezone.utc) if effect_mode == "scheduled" and not starts_at: return False if starts_at and reference_time < starts_at: return False if ends_at and reference_time > ends_at: return False if effect_mode in {"disabled", "inactive", "draft", "archived"}: return False return True def _current_policy_version_row( scope_row: dict[str, Any] | None, *, active_only: bool = False, ) -> dict[str, Any] | None: if not scope_row: return None if scope_row.get("current_version_id") and not active_only: row = legacy.db.fetch_one( "SELECT * FROM agent_policy_versions WHERE id = ?", (scope_row["current_version_id"],), ) if row: return row rows = legacy.db.fetch_all( """ SELECT * FROM agent_policy_versions WHERE scope_id = ? ORDER BY version_no DESC, created_at DESC """, (scope_row["id"],), ) if not rows: return None if not active_only: return rows[0] reference_time = datetime.now(timezone.utc) for row in rows: effectivity_row = _policy_effectivity_row(row["id"]) if _policy_effectivity_is_active(effectivity_row, current_time=reference_time): return row return None def _policy_effectivity_row(version_id: str) -> dict[str, Any] | None: return legacy.db.fetch_one( "SELECT * FROM agent_policy_effectivity WHERE version_id = ?", (version_id,), ) def _policy_scope_bundle( scope_row: dict[str, Any] | None, *, fallback_kind: str = "", fallback_platform: str = "", fallback_user_id: str = "", fallback_project_id: str = "", active_only: bool = False, ) -> dict[str, Any]: current_version_row = _current_policy_version_row(scope_row, active_only=active_only) effectivity_row = _policy_effectivity_row(current_version_row["id"]) if current_version_row else None return { "scope": _policy_scope_payload( scope_row, fallback_kind=fallback_kind, fallback_platform=fallback_platform, fallback_user_id=fallback_user_id, fallback_project_id=fallback_project_id, ), "current_version": _policy_version_payload(current_version_row), "effectivity": _policy_effectivity_payload(effectivity_row), } def _list_policy_versions(scope_row: dict[str, Any] | None) -> list[dict[str, Any]]: if not scope_row: return [] rows = legacy.db.fetch_all( """ SELECT * FROM agent_policy_versions WHERE scope_id = ? ORDER BY version_no DESC, created_at DESC """, (scope_row["id"],), ) return [_policy_version_payload(row) for row in rows] def _log_policy_audit( *, scope_id: str, version_id: str, actor_user_id: str, action_key: str, summary: str, details: dict[str, Any] | None = None, ) -> dict[str, Any]: audit_id = make_id("policy_audit") legacy.db.execute( """ INSERT INTO agent_policy_audit_logs ( id, scope_id, version_id, actor_user_id, action_key, summary, details_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, ( audit_id, scope_id, version_id, actor_user_id, action_key, summary, _dump(details or {}), now(), ), ) row = legacy.db.fetch_one("SELECT * FROM agent_policy_audit_logs WHERE id = ?", (audit_id,)) assert row is not None return _policy_audit_payload(row) def _policy_audit_record_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: if not row: return None payload = _policy_audit_payload(row) or {} scope_row = legacy.db.fetch_one("SELECT * FROM agent_policy_scopes WHERE id = ?", (row.get("scope_id", ""),)) if row.get("scope_id") else None version_row = legacy.db.fetch_one("SELECT * FROM agent_policy_versions WHERE id = ?", (row.get("version_id", ""),)) if row.get("version_id") else None scope_kind = (scope_row or {}).get("scope_kind", "") or (version_row or {}).get("scope_kind", "") platform = (scope_row or {}).get("platform", "") or (version_row or {}).get("platform", "") subject_user_id = (scope_row or {}).get("subject_user_id", "") or (version_row or {}).get("subject_user_id", "") subject_project_id = (scope_row or {}).get("subject_project_id", "") or (version_row or {}).get("subject_project_id", "") payload.update( { "scope_kind": scope_kind, "subject_user_id": subject_user_id, "subject_project_id": subject_project_id, "platform": platform, "platform_label": legacy.platform_label(platform) if platform else "", "scope": _policy_scope_payload( scope_row, fallback_kind=scope_kind, fallback_platform=platform, fallback_user_id=subject_user_id, fallback_project_id=subject_project_id, ), "version": _policy_version_payload(version_row), } ) return payload def _policy_audit_record_public_payload(row: dict[str, Any] | None) -> dict[str, Any] | None: payload = _policy_audit_record_payload(row) if not payload: return None payload.pop("actor_user_id", None) payload["details"] = _policy_public_audit_details(payload.get("details")) payload["version"] = _policy_version_public_payload( legacy.db.fetch_one("SELECT * FROM agent_policy_versions WHERE id = ?", (payload.get("version_id", ""),)) ) if payload.get("version_id") else None return payload def _fetch_policy_audit_records( where_sql: str, params: tuple[Any, ...], *, limit: int = 20, public_view: bool = False, ) -> list[dict[str, Any]]: rows = legacy.db.fetch_all( f""" SELECT audit.* FROM agent_policy_audit_logs audit JOIN agent_policy_scopes scope ON scope.id = audit.scope_id {where_sql} ORDER BY audit.created_at DESC LIMIT ? """, params + (limit,), ) builder = _policy_audit_record_public_payload if public_view else _policy_audit_record_payload return [builder(row) for row in rows if row] def _create_policy_version( scope_row: dict[str, Any], *, actor_user_id: str, title: str, summary: str, policy: dict[str, Any], effect_mode: str, starts_at: str, ends_at: str, config: dict[str, Any], reason: str, source_type: str, rollback_from_version_id: str = "", ) -> dict[str, Any]: current = legacy.db.fetch_one( "SELECT COALESCE(MAX(version_no), 0) AS max_version FROM agent_policy_versions WHERE scope_id = ?", (scope_row["id"],), ) version_no = int((current or {}).get("max_version") or 0) + 1 version_id = make_id("policy_ver") effectivity_id = make_id("policy_eff") timestamp = now() legacy.db.execute( """ INSERT INTO agent_policy_versions ( id, scope_id, scope_kind, subject_user_id, subject_project_id, platform, version_no, title, summary, policy_json, reason, source_type, rollback_from_version_id, actor_user_id, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( version_id, scope_row["id"], scope_row.get("scope_kind", ""), scope_row.get("subject_user_id", ""), scope_row.get("subject_project_id", ""), scope_row.get("platform", ""), version_no, title.strip() or scope_row.get("title") or _policy_scope_default_title(scope_row.get("scope_kind", ""), platform=scope_row.get("platform", "")), summary.strip(), _dump(policy), reason.strip(), source_type, rollback_from_version_id, actor_user_id, timestamp, ), ) legacy.db.execute( """ INSERT INTO agent_policy_effectivity ( id, scope_id, version_id, effect_mode, starts_at, ends_at, status, config_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, 'active', ?, ?, ?) """, ( effectivity_id, scope_row["id"], version_id, (effect_mode or "ongoing").strip() or "ongoing", starts_at.strip(), ends_at.strip(), _dump(config), timestamp, timestamp, ), ) legacy.db.execute( """ UPDATE agent_policy_scopes SET title = ?, summary = ?, current_version_id = ?, status = 'active', updated_at = ? WHERE id = ? """, ( title.strip() or scope_row.get("title") or _policy_scope_default_title(scope_row.get("scope_kind", ""), platform=scope_row.get("platform", "")), summary.strip(), version_id, timestamp, scope_row["id"], ), ) row = legacy.db.fetch_one("SELECT * FROM agent_policy_scopes WHERE id = ?", (scope_row["id"],)) assert row is not None return _policy_scope_bundle(row) def _rollback_policy_scope( scope_row: dict[str, Any], *, actor_user_id: str, version_id: str, reason: str, source_type: str, ) -> dict[str, Any]: target_version = legacy.db.fetch_one( "SELECT * FROM agent_policy_versions WHERE id = ? AND scope_id = ?", (version_id, scope_row["id"]), ) if not target_version: raise HTTPException(status_code=404, detail="Policy version not found") target_effectivity = _policy_effectivity_row(target_version["id"]) or {} bundle = _create_policy_version( scope_row, actor_user_id=actor_user_id, title=target_version.get("title", ""), summary=target_version.get("summary", ""), policy=_parse_json(target_version.get("policy_json"), {}), effect_mode=target_effectivity.get("effect_mode", "ongoing"), starts_at=target_effectivity.get("starts_at", ""), ends_at=target_effectivity.get("ends_at", ""), config=_parse_json(target_effectivity.get("config_json"), {}), reason=reason.strip() or f"回滚到版本 {target_version.get('version_no') or version_id}", source_type=source_type, rollback_from_version_id=target_version["id"], ) return bundle def _load_policy_subject_account(user_id: str) -> dict[str, Any]: row = legacy.db.fetch_one("SELECT * FROM accounts WHERE id = ?", (user_id,)) if not row: raise HTTPException(status_code=404, detail="Target account not found") return row def _load_policy_subject_project(*, user_id: str, project_id: str) -> dict[str, Any]: row = legacy.db.fetch_one("SELECT * FROM projects WHERE id = ?", (project_id,)) if not row: raise HTTPException(status_code=404, detail="Target project not found") if user_id and row.get("user_id") != user_id: raise HTTPException(status_code=400, detail="Target project does not belong to target user") return row def _governance_directory_payload() -> dict[str, Any]: account_rows = legacy.db.fetch_all( """ SELECT id, username, display_name, role, approval_status, created_at, updated_at FROM accounts WHERE approval_status = 'approved' ORDER BY CASE WHEN role = 'super_admin' THEN 0 ELSE 1 END ASC, updated_at DESC, created_at DESC """ ) project_rows = legacy.db.fetch_all( """ SELECT id, user_id, name, description, created_at, updated_at FROM projects ORDER BY updated_at DESC, created_at DESC """ ) projects_by_user: dict[str, list[dict[str, Any]]] = {} for row in project_rows: projects_by_user.setdefault(row.get("user_id", ""), []).append( { "id": row["id"], "user_id": row.get("user_id", ""), "name": row.get("name", ""), "description": row.get("description", ""), "created_at": row.get("created_at", ""), "updated_at": row.get("updated_at", ""), } ) items = [] for row in account_rows: projects = projects_by_user.get(row["id"], []) items.append( { "id": row["id"], "username": row.get("username", ""), "display_name": row.get("display_name", ""), "role": row.get("role", ""), "approval_status": row.get("approval_status", ""), "project_count": len(projects), "projects": projects, "created_at": row.get("created_at", ""), "updated_at": row.get("updated_at", ""), } ) return {"items": items, "count": len(items)} def _effective_policy_payload( *, subject_account: dict[str, Any], subject_project_id: str, platform: str, ) -> dict[str, Any]: normalized_platform = _normalize_policy_platform(platform) candidate_scopes: list[dict[str, Any]] = [] seen_scope_ids: set[str] = set() def add_candidate(scope_row: dict[str, Any] | None) -> None: if not scope_row or not scope_row.get("id"): return if scope_row["id"] in seen_scope_ids: return seen_scope_ids.add(scope_row["id"]) candidate_scopes.append(scope_row) add_candidate(_policy_scope_row(scope_kind="system_main")) if normalized_platform: add_candidate(_policy_scope_row(scope_kind="system_platform", platform=normalized_platform)) add_candidate( _policy_scope_row(scope_kind="user_global", subject_user_id=subject_account["id"], subject_project_id=subject_project_id) ) if normalized_platform: add_candidate( _policy_scope_row( scope_kind="user_platform", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, ) ) add_candidate( _policy_scope_row(scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id="", platform="") ) if normalized_platform: add_candidate( _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id="", platform=normalized_platform, ) ) if subject_project_id: add_candidate( _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform="", ) ) if normalized_platform: add_candidate( _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, ) ) layers: list[dict[str, Any]] = [] effective_policy: dict[str, Any] = {} for scope_row in candidate_scopes: if not scope_row: continue bundle = _policy_scope_bundle(scope_row, active_only=True) version = bundle.get("current_version") if not version: continue layer_policy = dict(version.get("policy") or {}) effective_policy = _deep_merge_policy(effective_policy, layer_policy) layers.append( { "scope_kind": bundle["scope"]["scope_kind"], "scope": bundle["scope"], "current_version": version, "effectivity": bundle.get("effectivity"), } ) active_admin_override_notice = next( ( { "scope_id": layer["scope"].get("id", ""), "version_id": (layer.get("current_version") or {}).get("id", ""), "title": (layer.get("current_version") or {}).get("title") or layer["scope"].get("title") or "管理员覆盖生效中", "summary": (layer.get("current_version") or {}).get("summary") or layer["scope"].get("summary") or "", "platform": layer["scope"].get("platform", ""), "platform_label": layer["scope"].get("platform_label", ""), "subject_project_id": layer["scope"].get("subject_project_id", ""), "created_at": (layer.get("current_version") or {}).get("created_at", ""), } for layer in reversed(layers) if layer.get("scope_kind") == "admin_override" ), None, ) return { "user_id": subject_account["id"], "project_id": subject_project_id, "platform": normalized_platform, "platform_label": legacy.platform_label(normalized_platform) if normalized_platform else "", "layers": layers, "effective_policy": effective_policy, "active_admin_override_notice": active_admin_override_notice, } def _bundle_with_versions( scope_row: dict[str, Any] | None, *, fallback_kind: str, fallback_platform: str = "", fallback_user_id: str = "", fallback_project_id: str = "", active_version_only: bool = False, ) -> dict[str, Any]: bundle = _policy_scope_bundle( scope_row, fallback_kind=fallback_kind, fallback_platform=fallback_platform, fallback_user_id=fallback_user_id, fallback_project_id=fallback_project_id, active_only=active_version_only, ) versions = _list_policy_versions(scope_row) bundle["versions"] = {"items": versions, "count": len(versions)} return bundle def _fix_run_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "incident_id": row.get("incident_id", ""), "actor_user_id": row.get("actor_user_id", ""), "tenant_user_id": row.get("tenant_user_id", ""), "tenant_project_id": row.get("tenant_project_id", ""), "plan_scope": row.get("plan_scope", "plan"), "status": row.get("status", "planned"), "audit_status": row.get("audit_status", "pending"), "review_notes": row.get("review_notes", ""), "plan": _parse_json(row.get("plan_json"), {}), "verification": _parse_json(row.get("verification_json"), {}), "created_at": row.get("created_at", ""), "updated_at": row.get("updated_at", ""), } def _tenant_quota_payload(row: dict[str, Any] | None, *, usage: dict[str, Any] | None = None) -> dict[str, Any]: data = row or {} config = _tenant_quota_config(data) return { "id": data.get("id", ""), "user_id": data.get("user_id", ""), "project_id": data.get("project_id", ""), "package_label": config["package_label"], "monthly_budget_cents": int(data.get("monthly_budget_cents") or 0), "storage_limit_bytes": int(data.get("storage_limit_bytes") or 0), "analysis_quota": int(data.get("analysis_quota") or 0), "copy_quota": int(data.get("copy_quota") or 0), "ai_video_quota": int(data.get("ai_video_quota") or 0), "real_cut_quota": int(data.get("real_cut_quota") or 0), "recorder_quota": int(data.get("recorder_quota") or 0), "enabled": True if row is None else _bool_flag(data.get("enabled", 1)), "config": config, "usage": usage or {}, "created_at": data.get("created_at", ""), "updated_at": data.get("updated_at", ""), } def _tenant_usage_payload(row: dict[str, Any]) -> dict[str, Any]: return { "id": row["id"], "user_id": row.get("user_id", ""), "project_id": row.get("project_id", ""), "category": row.get("category", ""), "quantity": int(row.get("quantity") or 0), "cost_cents": int(row.get("cost_cents") or 0), "reference_type": row.get("reference_type", ""), "reference_id": row.get("reference_id", ""), "details": _parse_json(row.get("details_json"), {}), "created_at": row.get("created_at", ""), } def _log_admin_audit_event( *, actor_user_id: str, incident_id: str = "", action_key: str, status: str, summary: str, details: dict[str, Any] | None = None, ) -> dict[str, Any]: audit_id = make_id("ops_audit") timestamp = now() sql = """ INSERT INTO admin_ops_audit_logs ( id, actor_user_id, incident_id, action_key, status, summary, details_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """ params = ( audit_id, actor_user_id, incident_id, action_key, status, summary, _dump(details or {}), timestamp, ) if incident_id: legacy.db.execute(sql, params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(sql, params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM admin_ops_audit_logs WHERE id = ?", (audit_id,)) return _admin_audit_payload(row) def _project_storage_bytes(account: dict[str, Any], *, project_id: str) -> int: try: payload = legacy.storage_status(project_id=project_id, account=account) except Exception: return 0 tenant_usage = payload.get("tenant_usage", {}) if isinstance(payload, dict) else {} jobs_bytes = int((((tenant_usage.get("project_jobs") or {}).get("bytes")) or 0)) downloads_bytes = int((((tenant_usage.get("project_downloads") or {}).get("bytes")) or 0)) return jobs_bytes + downloads_bytes def _tenant_usage_summary(account: dict[str, Any], *, project_id: str) -> dict[str, Any]: cycle_start = _current_cycle_start() rows = legacy.db.fetch_all( """ SELECT category, SUM(quantity) AS quantity, SUM(cost_cents) AS cost_cents FROM tenant_usage_ledger WHERE user_id = ? AND project_id = ? AND created_at >= ? GROUP BY category ORDER BY category ASC """, (account["id"], project_id, cycle_start), ) by_category: dict[str, dict[str, Any]] = {} for row in rows: category = row.get("category", "") by_category[category] = { "category": category, "quantity": int(row.get("quantity") or 0), "cost_cents": int(row.get("cost_cents") or 0), } recent_rows = legacy.db.fetch_all( """ SELECT * FROM tenant_usage_ledger WHERE user_id = ? AND project_id = ? ORDER BY created_at DESC LIMIT 20 """, (account["id"], project_id), ) total_cost = sum(item["cost_cents"] for item in by_category.values()) storage_bytes = _project_storage_bytes(account, project_id=project_id) return { "cycle_start": cycle_start, "categories": by_category, "total_cost_cents": total_cost, "recent_items": [_tenant_usage_payload(row) for row in recent_rows], "storage_bytes": storage_bytes, } def _get_tenant_quota_row(account: dict[str, Any], *, project_id: str) -> dict[str, Any] | None: return legacy.db.fetch_one( "SELECT * FROM tenant_quota_profiles WHERE user_id = ? AND project_id = ?", (account["id"], project_id), ) def _get_tenant_quota(account: dict[str, Any], *, project_id: str) -> dict[str, Any]: usage = _tenant_usage_summary(account, project_id=project_id) row = _get_tenant_quota_row(account, project_id=project_id) payload = _tenant_quota_payload(row, usage=usage) storage_limit = int(payload.get("storage_limit_bytes") or 0) payload["storage_over_limit"] = bool(storage_limit and usage["storage_bytes"] >= storage_limit) return payload def _record_tenant_usage( account: dict[str, Any], *, project_id: str, category: str, reference_type: str, reference_id: str, details: dict[str, Any] | None = None, quantity: int = 1, ) -> dict[str, Any]: usage_meta = USAGE_COST_DEFAULTS.get(category, {}) usage_id = make_id("usage") legacy.db.execute( """ INSERT INTO tenant_usage_ledger ( id, user_id, project_id, category, quantity, cost_cents, reference_type, reference_id, details_json, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( usage_id, account["id"], project_id, category, int(quantity or 1), int(usage_meta.get("cost_cents") or 0) * int(quantity or 1), reference_type, reference_id, _dump(details or {}), now(), ), ) row = legacy.db.fetch_one("SELECT * FROM tenant_usage_ledger WHERE id = ?", (usage_id,)) return _tenant_usage_payload(row) def _enforce_tenant_quota(account: dict[str, Any], *, project_id: str, usage_category: str) -> None: quota = _get_tenant_quota(account, project_id=project_id) if not quota.get("enabled", True): return usage = quota.get("usage", {}) category_meta = USAGE_COST_DEFAULTS.get(usage_category, {}) quota_field = category_meta.get("quota_field") if quota_field: allowed = int(quota.get(quota_field) or 0) consumed = int(((usage.get("categories") or {}).get(usage_category) or {}).get("quantity") or 0) if allowed and consumed >= allowed: raise HTTPException(status_code=403, detail=f"当前租户本周期的 {usage_category} 配额已用完") budget = int(quota.get("monthly_budget_cents") or 0) total_cost = int((usage.get("total_cost_cents") or 0)) next_cost = int(category_meta.get("cost_cents") or 0) if budget and total_cost + next_cost > budget: raise HTTPException(status_code=403, detail="当前租户本周期预算不足,已阻止本次动作执行") storage_limit = int(quota.get("storage_limit_bytes") or 0) if storage_limit and usage_category in {"analysis", "content_source_sync", "ai_video", "real_cut"}: storage_bytes = int(usage.get("storage_bytes") or 0) if storage_bytes >= storage_limit: raise HTTPException(status_code=403, detail="当前租户存储额度已满,已阻止继续产生大文件缓存") def _platform_source_samples( account: dict[str, Any], *, project_id: str, platform: str, limit: int = 3, ) -> list[dict[str, Any]]: safe_limit = max(1, min(int(limit or 3), 12)) rows = legacy.db.fetch_all( f""" SELECT * FROM content_sources WHERE user_id = ? AND project_id = ? AND platform = ? ORDER BY updated_at DESC LIMIT {safe_limit} """, (account["id"], project_id, platform), ) return [legacy.content_source_payload(row) for row in rows] def _resolve_execution_assistant(account: dict[str, Any], *, project_id: str, platform: str = "") -> dict[str, Any] | None: normalized_platform = _safe_platform(platform or "", fallback="") if normalized_platform: profile_row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project_id, normalized_platform), ) if profile_row and profile_row.get("assistant_id"): assistant = _resolve_assistant(account, profile_row.get("assistant_id"), project_id) if assistant: return assistant profile_row = _fetch_profile_row(account, project_id) or _ensure_oneliner_profile(account, project_id) if profile_row.get("assistant_id"): assistant = _resolve_assistant(account, profile_row.get("assistant_id"), project_id) if assistant: return assistant return _resolve_assistant(account, None, project_id) def _latest_project_job(account: dict[str, Any], *, project_id: str) -> dict[str, Any] | None: return legacy.db.fetch_one( """ SELECT * FROM jobs WHERE user_id = ? AND project_id = ? AND status IN ('completed', 'done', 'succeeded') ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"], project_id), ) def _last_user_message_text(session_id: str, account_id: str) -> str: row = legacy.db.fetch_one( """ SELECT * FROM oneliner_messages WHERE session_id = ? AND user_id = ? AND role = 'user' ORDER BY created_at DESC LIMIT 1 """, (session_id, account_id), ) return str((row or {}).get("content") or "").strip() def _extract_first_url(text: str) -> str: cleaned = str(text or "").strip() if not cleaned: return "" match = re.search(r"https?://[^\s<>'\"]+", cleaned) if not match: return "" return match.group(0).rstrip(",。;;,.)]》】!?!?") def _find_creator_source_by_url( account: dict[str, Any], *, project_id: str, platform: str, source_url: str, ) -> dict[str, Any] | None: return legacy.db.fetch_one( """ SELECT * FROM content_sources WHERE user_id = ? AND project_id = ? AND platform = ? AND source_kind = 'creator_account' AND source_url = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"], project_id, platform, source_url), ) def _latest_platform_account( account: dict[str, Any], *, project_id: str, platform: str, ) -> dict[str, Any] | None: return legacy.db.fetch_one( """ SELECT * FROM content_sources WHERE user_id = ? AND project_id = ? AND platform = ? AND source_kind = 'creator_account' ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"], project_id, platform), ) def _latest_douyin_account( account: dict[str, Any], *, project_id: str, ) -> dict[str, Any] | None: return legacy.db.fetch_one( """ SELECT * FROM douyin_accounts WHERE user_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"],), ) def _resolve_platform_target_account( account: dict[str, Any], *, project_id: str, platform: str, requested_account_id: str = "", ) -> dict[str, Any] | None: normalized_platform = _safe_platform(platform, fallback="douyin") normalized_requested = str(requested_account_id or "").strip() if normalized_platform == "douyin": if normalized_requested: return legacy.db.fetch_one( "SELECT * FROM douyin_accounts WHERE id = ? AND user_id = ?", (normalized_requested, account["id"]), ) return _latest_douyin_account(account, project_id=project_id) if normalized_requested: return legacy.db.fetch_one( """ SELECT * FROM content_sources WHERE id = ? AND user_id = ? AND project_id = ? AND platform = ? AND source_kind = 'creator_account' """, (normalized_requested, account["id"], project_id, normalized_platform), ) return _latest_platform_account(account, project_id=project_id, platform=normalized_platform) def _latest_similarity_candidate( account: dict[str, Any], *, platform: str, source_account_id: str, ) -> dict[str, Any] | None: normalized_platform = _safe_platform(platform, fallback="douyin") normalized_source_id = str(source_account_id or "").strip() if not normalized_source_id: return None table_prefix = "douyin" if normalized_platform == "douyin" else normalized_platform search_row = legacy.db.fetch_one( f""" SELECT * FROM {table_prefix}_similarity_searches WHERE user_id = ? AND source_account_id = ? ORDER BY created_at DESC LIMIT 1 """, (account["id"], normalized_source_id), ) if not search_row: return None candidate_row = legacy.db.fetch_one( f""" SELECT * FROM {table_prefix}_similarity_candidates WHERE search_id = ? ORDER BY rank_index ASC LIMIT 1 """, (search_row["id"],), ) if not candidate_row: return {"search_id": search_row["id"], "candidate": {}} candidate_payload = _parse_json(candidate_row.get("raw_output_json") or "{}", {}) candidate_payload.setdefault("candidate_account_id", candidate_row.get("candidate_account_id", "")) candidate_payload.setdefault("candidate_profile_url", candidate_row.get("candidate_profile_url", "")) candidate_payload.setdefault("candidate_nickname", candidate_row.get("candidate_nickname", "")) candidate_payload.setdefault("rationale_text", candidate_row.get("rationale_text", "")) candidate_payload.setdefault("agent_score", candidate_row.get("agent_score", 0)) candidate_payload.setdefault("heuristic_score", candidate_row.get("heuristic_score", 0)) return { "search_id": search_row["id"], "candidate": candidate_payload, } async def _call_local_api( account: dict[str, Any], *, method: str, path: str, json_body: dict[str, Any] | None = None, query: dict[str, Any] | None = None, ) -> Any: issued = legacy.issue_auth_token(account, mode="internal") token = issued["token"] transport = httpx.ASGITransport(app=app) try: async with httpx.AsyncClient(transport=transport, base_url="http://storyforge.internal") as client: response = await client.request( method.upper(), path, params=query or None, json=json_body, headers={"Authorization": f"Bearer {token}"}, timeout=60.0, ) if response.status_code >= 400: try: payload = response.json() except Exception: payload = {"detail": response.text} detail = payload.get("detail", payload) raise HTTPException(status_code=response.status_code, detail=detail) if not response.content: return {} return response.json() finally: legacy.db.execute("DELETE FROM auth_tokens WHERE token = ?", (token,)) def _load_owned_job(account: dict[str, Any], job_id: str) -> dict[str, Any] | None: normalized_job_id = str(job_id or "").strip() if not normalized_job_id: return None return legacy.db.fetch_one( "SELECT * FROM jobs WHERE id = ? AND user_id = ?", (normalized_job_id, account["id"]), ) def _latest_derivable_job( account: dict[str, Any], *, project_id: str, exclude_line_types: set[str] | None = None, ) -> dict[str, Any] | None: excluded = {item.strip() for item in (exclude_line_types or set()) if str(item or "").strip()} rows = legacy.db.fetch_all( """ SELECT * FROM jobs WHERE user_id = ? AND project_id = ? AND status IN ('completed', 'done', 'succeeded') ORDER BY updated_at DESC, created_at DESC LIMIT 24 """, (account["id"], project_id), ) for row in rows: if str(row.get("line_type") or "").strip() in excluded: continue return row return rows[0] if rows else None def _job_performance_score(job_row: dict[str, Any] | None) -> float: if not job_row: return 0.0 result_map = _parse_json(job_row.get("result_json") or "{}", {}) artifacts_map = _parse_json(job_row.get("artifacts_json") or "{}", {}) candidates = [ result_map.get("performance_score"), (result_map.get("analysis") or {}).get("performance_score"), (result_map.get("scores") or {}).get("performance_score"), artifacts_map.get("performance_score"), (artifacts_map.get("scores") or {}).get("performance_score"), ] for value in candidates: try: return float(value) except (TypeError, ValueError): continue return 0.0 def _linked_platform_videos( account: dict[str, Any], *, project_id: str, platform: str, account_row: dict[str, Any], limit: int = 8, ) -> list[dict[str, Any]]: rows = legacy.db.fetch_all( """ SELECT * FROM content_sources WHERE user_id = ? AND project_id = ? AND platform = ? AND source_kind = 'video_link' ORDER BY updated_at DESC, created_at DESC """, (account["id"], project_id, platform), ) account_source_url = str(account_row.get("source_url") or "").strip() items: list[dict[str, Any]] = [] for row in rows: payload = legacy.content_source_payload(row) metadata = payload.get("metadata") or {} if metadata.get("origin_content_source_id") != account_row["id"] and metadata.get("source_account_url") != account_source_url: continue latest_job = legacy.db.fetch_one( "SELECT * FROM jobs WHERE content_source_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1", (row["id"],), ) result_map = _parse_json((latest_job or {}).get("result_json") or "{}", {}) published_at = ( metadata.get("published_at") or metadata.get("publish_time") or metadata.get("created_at") or payload.get("updated_at") or payload.get("created_at") or "" ) items.append( { "id": payload["id"], "title": payload.get("title") or payload.get("handle") or payload.get("source_url") or payload["id"], "source_url": payload.get("source_url", ""), "published_at": published_at, "score": { "performance_score": _job_performance_score(latest_job), }, "latest_job_id": (latest_job or {}).get("id", ""), "latest_job_status": (latest_job or {}).get("status", ""), "summary": str(result_map.get("summary") or result_map.get("headline_summary") or "")[:240], } ) items.sort(key=lambda item: (float((item.get("score") or {}).get("performance_score") or 0), item.get("published_at") or ""), reverse=True) return items[: max(1, min(int(limit or 8), 16))] def _fallback_platform_videos( account: dict[str, Any], *, project_id: str, platform: str, requested_account_id: str = "", limit: int = 8, ) -> tuple[dict[str, Any] | None, list[dict[str, Any]]]: safe_limit = max(1, min(int(limit or 8), 16)) if platform == "douyin": target_account = None if requested_account_id: target_account = legacy.db.fetch_one( "SELECT * FROM douyin_accounts WHERE id = ? AND user_id = ?", (requested_account_id, account["id"]), ) if not target_account: target_account = legacy.db.fetch_one( "SELECT * FROM douyin_accounts WHERE user_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1", (account["id"],), ) if not target_account: return None, [] rows = legacy.db.fetch_all( """ SELECT * FROM douyin_videos WHERE account_id = ? ORDER BY COALESCE(published_at, updated_at) DESC, updated_at DESC LIMIT ? """, (target_account["id"], safe_limit), ) items: list[dict[str, Any]] = [] for row in rows: stats = _parse_json(row.get("stats_json") or "{}", {}) play_count = float(stats.get("play_count") or stats.get("play") or 0) like_count = float(stats.get("digg_count") or stats.get("like_count") or 0) comment_count = float(stats.get("comment_count") or 0) share_count = float(stats.get("share_count") or 0) score = min( 100.0, play_count / 10000 * 55 + like_count / 1000 * 25 + comment_count / 100 * 10 + share_count / 100 * 10, ) items.append( { "id": row["id"], "title": row.get("title") or row.get("description") or row.get("share_url") or row["id"], "source_url": row.get("share_url", ""), "published_at": row.get("published_at") or "", "score": {"performance_score": round(score, 2)}, "latest_job_id": "", "latest_job_status": "", "summary": "", } ) account_payload = { "id": target_account["id"], "title": target_account.get("nickname") or target_account.get("douyin_id") or "抖音账号", "handle": target_account.get("douyin_id") or "", "source_url": target_account.get("canonical_profile_url") or target_account.get("profile_url") or "", "platform": "douyin", } items.sort(key=lambda item: (float((item.get("score") or {}).get("performance_score") or 0), item.get("published_at") or ""), reverse=True) return account_payload, items[:safe_limit] source_account = _latest_platform_account(account, project_id=project_id, platform=platform) if not source_account: return None, [] source_payload = legacy.content_source_payload(source_account) metadata = source_payload.get("metadata") or {} summary_videos = ((metadata.get("video_summary") or {}).get("videos") or [])[:safe_limit] items = [] for item in summary_videos: score = float(item.get("performance_score") or item.get("score") or 0) items.append( { "id": str(item.get("id") or item.get("aweme_id") or item.get("video_id") or make_id(f"{platform}_video")), "title": str(item.get("title") or item.get("description") or item.get("share_url") or "平台作品"), "source_url": str(item.get("share_url") or item.get("url") or ""), "published_at": str(item.get("published_at") or item.get("publish_time") or ""), "score": {"performance_score": score}, "latest_job_id": "", "latest_job_status": "", "summary": "", } ) items.sort(key=lambda item: (float((item.get("score") or {}).get("performance_score") or 0), item.get("published_at") or ""), reverse=True) return source_payload, items[:safe_limit] def _assistant_brief_from_job(job_row: dict[str, Any] | None) -> str: if not job_row: return "" result_map = _parse_json(job_row.get("result_json") or "{}", {}) artifacts_map = _parse_json(job_row.get("artifacts_json") or "{}", {}) candidates = [ result_map.get("summary"), result_map.get("headline_summary"), artifacts_map.get("summary"), artifacts_map.get("objective"), artifacts_map.get("brief"), job_row.get("title"), ] for value in candidates: cleaned = str(value or "").strip() if cleaned: return cleaned[:480] return "" def _load_owned_session(session_id: str, account: dict[str, Any]) -> dict[str, Any]: row = legacy.db.fetch_one( "SELECT * FROM oneliner_sessions WHERE id = ? AND user_id = ?", (session_id, account["id"]), ) if not row: raise HTTPException(status_code=404, detail="OneLiner session not found") return row def _load_owned_agent_run(run_id: str, account: dict[str, Any]) -> dict[str, Any]: row = legacy.db.fetch_one( "SELECT * FROM agent_runs WHERE id = ? AND user_id = ?", (run_id, account["id"]), ) if not row: raise HTTPException(status_code=404, detail="OneLiner run not found") return row def _normalize_platform_scope(value: str | None) -> str: normalized = str(value or "").strip().lower() if normalized == "all_platforms": return "all_platforms" return "single_platform" def _normalize_delivery_mode(value: str | None) -> str: normalized = str(value or "").strip().lower() if normalized in {"ui", "oneliner", "hybrid"}: return normalized return "hybrid" def _normalize_scheduling_mode(value: str | None) -> str: normalized = str(value or "").strip().lower() if normalized == "parallel": return "parallel" return "queued" def _ensure_run_session( account: dict[str, Any], *, project_id: str, requested_session_id: str, title: str, preferred_platform: str, ) -> dict[str, Any]: if requested_session_id: return _load_owned_session(requested_session_id, account) latest_row = legacy.db.fetch_one( """ SELECT * FROM oneliner_sessions WHERE user_id = ? AND project_id = ? ORDER BY updated_at DESC, created_at DESC LIMIT 1 """, (account["id"], project_id), ) if latest_row: return latest_row profile = _fetch_profile_row(account, project_id) session_id = make_id("oline") timestamp = now() legacy.db.execute( """ INSERT INTO oneliner_sessions ( id, user_id, project_id, profile_id, title, status, preferred_platform, last_platform, last_intent_key, last_message_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, 'active', ?, '', '', ?, ?, ?) """, ( session_id, account["id"], project_id, (profile or {}).get("id"), title.strip() or "新的 OneLiner 会话", preferred_platform, timestamp, timestamp, timestamp, ), ) created = legacy.db.fetch_one("SELECT * FROM oneliner_sessions WHERE id = ?", (session_id,)) assert created is not None return created def _touch_session_for_run(session_id: str, *, platform: str, intent_key: str) -> None: timestamp = now() legacy.db.execute( """ UPDATE oneliner_sessions SET last_platform = ?, last_intent_key = ?, last_message_at = ?, updated_at = ? WHERE id = ? """, (platform, intent_key, timestamp, timestamp, session_id), ) def _log_agent_run_event( run_id: str, *, event_type: str, summary: str, details: dict[str, Any] | None = None, ) -> dict[str, Any]: event_id = make_id("run_evt") legacy.db.execute( """ INSERT INTO agent_run_events (id, run_id, event_type, summary, details_json, created_at) VALUES (?, ?, ?, ?, ?, ?) """, ( event_id, run_id, event_type, summary, _dump(details or {}), now(), ), ) row = legacy.db.fetch_one("SELECT * FROM agent_run_events WHERE id = ?", (event_id,)) assert row is not None return _agent_run_event_payload(row) def _agent_run_plan_payload( request: AgentRunCreateRequest, *, governance: dict[str, Any], platform: str, platform_scope: str, ) -> dict[str, Any]: requested_plan = dict(request.plan_request or {}) requested_payload = dict(request.payload or {}) raw_steps = requested_plan.get("steps") or [] if not isinstance(raw_steps, list): raw_steps = [raw_steps] steps = [str(item).strip() for item in raw_steps if str(item).strip()] if not steps: steps = ["读取当前项目上下文", "结合治理层生成执行计划", "等待用户确认后执行"] requested_context: dict[str, Any] = {} for key in ( "target_account_id", "targetAccountId", "tracked_account_id", "trackedAccountId", "job_id", "source_job_id", "sourceJobId", "review_id", "reviewId", "source_id", "sourceId", "assistant_id", "assistantId", "platform", ): value = requested_payload.get(key) text = str(value or "").strip() if value is not None else "" if not text: continue normalized_key = { "targetAccountId": "target_account_id", "trackedAccountId": "tracked_account_id", "sourceJobId": "source_job_id", "reviewId": "review_id", "sourceId": "source_id", "assistantId": "assistant_id", }.get(key, key) requested_context[normalized_key] = text return { **requested_plan, "goal": str(requested_plan.get("goal") or request.title or "主 Agent 任务").strip() or "主 Agent 任务", "steps": steps, "intent_key": str(request.intent_key or "custom").strip() or "custom", "platform": platform, "platform_scope": platform_scope, "source_screen": str(request.source_screen or "").strip(), "source_action_key": str(request.source_action_key or "").strip(), "summary": str(request.summary or requested_plan.get("summary") or "").strip(), "requested_delivery_mode": _normalize_delivery_mode(request.delivery_mode), "requested_context": requested_context, "active_admin_override_notice": governance.get("active_admin_override_notice") or {}, } def _has_other_active_runs(*, account_id: str, project_id: str, run_id: str) -> bool: row = legacy.db.fetch_one( """ SELECT id FROM agent_runs WHERE user_id = ? AND project_id = ? AND id != ? AND run_status IN ('queued', 'running', 'blocked') ORDER BY updated_at DESC LIMIT 1 """, (account_id, project_id, run_id), ) return bool(row) def _build_agent_run_recommended_action(row: dict[str, Any], plan: dict[str, Any]) -> dict[str, Any]: source_screen = str(plan.get("source_screen") or row.get("source_screen") or "").strip().lower() source_action_key = str(plan.get("source_action_key") or row.get("source_action_key") or "").strip().lower() intent_key = str(plan.get("intent_key") or row.get("intent_key") or "custom").strip().lower() or "custom" requested_context = plan.get("requested_context") if isinstance(plan.get("requested_context"), dict) else {} def route(action: str, screen: str, label: str, summary: str, **extra: Any) -> dict[str, Any]: payload = { "action": action, "screen": screen, "label": label, "summary": summary, } for key, value in extra.items(): text = str(value or "").strip() if value is not None else "" if not text: continue payload[key] = value return payload target_account_id = str(requested_context.get("target_account_id") or "").strip() tracked_account_id = str(requested_context.get("tracked_account_id") or "").strip() job_id = str(requested_context.get("job_id") or requested_context.get("source_job_id") or "").strip() review_id = str(requested_context.get("review_id") or "").strip() source_id = str(requested_context.get("source_id") or "").strip() assistant_id = str(requested_context.get("assistant_id") or "").strip() if review_id: return route("open-review-edit", "review", "打开复盘", "继续回到当前复盘对象完善结论和动作。", review_id=review_id, job_id=job_id) if source_screen == "review" and job_id: return route("open-review-from-job", "review", "继续写复盘", "继续围绕这条任务生成或完善复盘。", job_id=job_id) if source_screen in {"discovery", "tracking"} and target_account_id: return route("select-account", "discovery", "打开当前对象", "继续围绕当前账号查看详情、对标和分析结果。", account_id=target_account_id) if source_screen == "tracking" and tracked_account_id: return route("refresh-tracked-account", "tracking", "继续同步当前账号", "继续同步这条已跟踪账号,并回看最近更新。", tracked_account_id=tracked_account_id) if source_screen == "production" and job_id: return route("open-job-detail", "production", "看任务详情", "继续回到当前任务,查看执行状态和后续动作。", job_id=job_id) if source_screen == "production" and source_id: return route("edit-live-recorder-source", "production", "继续录制维护", "继续查看当前录制源的启停和录制文件。", source_id=source_id) if source_screen in {"playbook", "agent"} and assistant_id: return route("open-edit-assistant", "playbook", "继续编辑 Agent", "继续围绕当前 Agent 调整目标、说明和承接能力。", assistant_id=assistant_id) source_routes = { "strategy": route("goto-strategy", "strategy", "回到我的策略", "继续查看当前用户策略与覆盖状态。"), "automation": route("goto-automation", "automation", "回到自动流程", "继续检查自动流程和依赖状态。"), "playbook": route("goto-playbook", "playbook", "回到 Agent", "继续调整 Agent 与平台能力。"), "agent": route("goto-playbook", "playbook", "回到 Agent", "继续调整 Agent 与平台能力。"), "production": route("goto-production", "production", "回到生产中心", "继续推进生产任务与恢复动作。"), "tracking": route("goto-tracking", "tracking", "回到跟踪账号", "继续查看跟踪摘要和更新提醒。"), "review": route("goto-review", "review", "回到发布与复盘", "继续沉淀复盘结论和发布结果。"), "discovery": route("goto-discovery", "discovery", "回到找对标", "继续查看账号拆解和高分样本。"), "intake": route("goto-intake", "projects", "回到我的项目", "继续切换项目或补齐项目基础信息。"), "projects": route("goto-intake", "projects", "回到我的项目", "继续切换项目或补齐项目基础信息。"), } if source_screen == "dashboard" and source_action_key == "homepage-primary-action": return route("goto-discovery", "discovery", "回到找对标", "继续查看首页当前最优先的对标与高分样本动作。") if source_screen == "dashboard" and source_action_key.startswith("homepage-secondary-action-"): if intent_key == "track_account": return route("goto-tracking", "tracking", "回到跟踪账号", "继续跟进首页建议的重点账号跟踪。") return route("goto-production", "production", "回到生产中心", "继续处理首页建议的生产推进动作。") if source_screen in source_routes: return source_routes[source_screen] intent_routes = { "analyze_account": route(target_account_id and "select-account" or "goto-discovery", "discovery", target_account_id and "打开当前对象" or "回到找对标", "继续拆解当前账号和对标对象。", account_id=target_account_id), "analyze_top_videos": route(target_account_id and "select-account" or "goto-discovery", "discovery", target_account_id and "打开当前对象" or "回到找对标", "继续查看高分作品分析结论。", account_id=target_account_id), "track_account": route(tracked_account_id and "refresh-tracked-account" or "goto-tracking", "tracking", tracked_account_id and "继续同步当前账号" or "回到跟踪账号", "继续更新账号跟踪与日报。", tracked_account_id=tracked_account_id), "ai_video": route(job_id and "open-job-detail" or "goto-production", "production", job_id and "看任务详情" or "回到生产中心", "继续推进 AI 视频生产任务。", job_id=job_id), "real_cut": route(job_id and "open-job-detail" or "goto-production", "production", job_id and "看任务详情" or "回到生产中心", "继续推进实拍剪辑任务。", job_id=job_id), "live_recorder": route(source_id and "edit-live-recorder-source" or "goto-production", "production", source_id and "继续录制维护" or "回到生产中心", "继续查看录制维护与产物。", source_id=source_id), "review": route(review_id and "open-review-edit" or job_id and "open-review-from-job" or "goto-review", "review", review_id and "打开复盘" or job_id and "继续写复盘" or "回到发布与复盘", "继续补齐复盘与发布总结。", review_id=review_id, job_id=job_id), "create_assistant": route(assistant_id and "open-edit-assistant" or "goto-playbook", "playbook", assistant_id and "继续编辑 Agent" or "回到 Agent", "继续创建或调整项目 Agent。", assistant_id=assistant_id), "create_project": route("goto-intake", "projects", "回到我的项目", "继续创建或切换当前项目。"), "import_homepage": route(target_account_id and "select-account" or "goto-discovery", "discovery", target_account_id and "打开当前对象" or "回到找对标", "继续处理主页导入后的账号分析。", account_id=target_account_id), "ops_admin": route("goto-automation", "automation", "回到自动流程", "继续查看系统依赖和治理状态。"), "storage_status": route("goto-automation", "automation", "回到自动流程", "继续查看存储与依赖健康状态。"), } if intent_key in intent_routes: return intent_routes[intent_key] return route("goto-production", "production", "回到生产中心", "继续推进当前主 Agent 任务的执行结果。") def _build_agent_run_result_sections( row: dict[str, Any], plan: dict[str, Any], recommended_action: dict[str, Any], ) -> dict[str, Any]: source_screen = str(plan.get("source_screen") or row.get("source_screen") or "").strip().lower() recommended_screen = str(recommended_action.get("screen") or "").strip().lower() screen_key = recommended_screen or source_screen intent_key = str(plan.get("intent_key") or row.get("intent_key") or "custom").strip().lower() or "custom" platform = str(plan.get("platform") or row.get("platform") or "").strip() platform_label = legacy.platform_label(platform) if platform else "" plan_summary = str(plan.get("summary") or row.get("summary") or "").strip() or "主 Agent 已按当前上下文完成首轮收口。" goal = str(plan.get("goal") or row.get("title") or "主 Agent 任务").strip() or "主 Agent 任务" override_notice = _parse_json(row.get("active_admin_override_notice_json"), {}) workstream_map = { "dashboard": ("dashboard", "首页动作"), "discovery": ("discovery", "对标推进"), "tracking": ("tracking", "跟踪推进"), "production": ("production", "生产推进"), "review": ("review", "复盘推进"), "strategy": ("strategy", "策略治理"), "playbook": ("playbook", "Agent 治理"), "agent": ("playbook", "Agent 治理"), "automation": ("automation", "自动流程"), "intake": ("intake", "项目推进"), "projects": ("intake", "项目推进"), } workstream_key, workstream_label = workstream_map.get(screen_key, ("production", "主 Agent 执行结果")) if intent_key in {"analyze_account", "analyze_top_videos", "import_homepage"}: workstream_key, workstream_label = "discovery", "对标推进" elif intent_key == "track_account": workstream_key, workstream_label = "tracking", "跟踪推进" elif intent_key in {"ai_video", "real_cut", "live_recorder"}: workstream_key, workstream_label = "production", "生产推进" elif intent_key == "review": workstream_key, workstream_label = "review", "复盘推进" elif intent_key in {"create_assistant"}: workstream_key, workstream_label = "playbook", "Agent 治理" elif intent_key in {"create_project"}: workstream_key, workstream_label = "intake", "项目推进" elif intent_key in {"storage_status", "ops_admin"}: workstream_key, workstream_label = "automation", "自动流程" def card(title: str, body: str, *, tone: str = "blue", tags: list[str] | None = None) -> dict[str, Any]: return { "title": title, "body": body, "tone": tone, "tags": [item for item in list(tags or []) if str(item).strip()], } cards = [ card( "当前焦点", f"围绕「{goal}」先完成一版可执行收口,避免你先在多个页面之间来回切换。", tone="blue", tags=[platform_label or "当前平台", workstream_label], ) ] focus_body_map = { "discovery": "优先回到找对标,继续看账号、相似关系和高分样本,再决定是否导入或加入跟踪。", "tracking": "优先回到跟踪账号,看最近日报窗口和值得继续跟进的对象,再决定同步或加深跟踪。", "production": "优先回到生产中心,看队列、失败恢复和产物,再决定下一步是推进还是补救。", "review": "优先回到发布与复盘,把最近完成任务沉淀成结构化复盘,再决定是否继续发布。", "strategy": "优先回到我的策略,先看当前生效层和管理员覆盖,再决定是否继续调整用户策略。", "playbook": "优先回到 Agent 工作区,结合当前平台 Agent、模型和技能,继续完善执行能力。", "automation": "优先回到自动流程,先看依赖健康和动作防呆,再决定是否恢复或放行动作。", "intake": "优先回到我的项目,先补项目、账号和导入基础,再决定往哪个工作页继续推进。", "dashboard": "优先回到首页当前推荐动作,把这一轮的重点从概览转成真实执行。", } cards.append( card( workstream_label, focus_body_map.get(workstream_key, plan_summary), tone="green", tags=[recommended_action.get("label") or "回到业务页"], ) ) cards.append( card( "建议落点", str(recommended_action.get("summary") or plan_summary).strip() or "回到对应业务页面继续推进。", tone="orange" if override_notice.get("title") else "blue", tags=[ recommended_action.get("screen") or "", "管理员覆盖生效中" if override_notice.get("title") else "", "全平台" if str(plan.get("platform_scope") or row.get("platform_scope") or "") == "all_platforms" else "单平台", ], ) ) if override_notice.get("title"): cards.append( card( "管理员覆盖提醒", str(override_notice.get("summary") or "当前执行会优先遵循管理员覆盖层。").strip(), tone="orange", tags=[str(override_notice.get("title") or "管理员覆盖").strip()], ) ) return { "workstream_key": workstream_key, "workstream_label": workstream_label, "cards": cards, } def _complete_agent_run_for_read(row: dict[str, Any]) -> dict[str, Any]: current_status = str(row.get("run_status") or "") run_id = str(row.get("id") or "") if not run_id: return row if current_status == "queued" and not _has_other_active_runs( account_id=str(row.get("user_id") or ""), project_id=str(row.get("project_id") or ""), run_id=run_id, ): timestamp = now() started_at = str(row.get("started_at") or timestamp) legacy.db.execute( """ UPDATE agent_runs SET run_status = 'running', status_summary = ?, updated_at = ?, started_at = ? WHERE id = ? """, ("主 Agent 正在执行", timestamp, started_at, run_id), ) _log_agent_run_event( run_id, event_type="run.started", summary="主 Agent 已开始执行", details={"run_status": "running"}, ) refreshed = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (run_id,)) if refreshed is not None: row = refreshed current_status = "running" if current_status != "running" or str(row.get("finished_at") or "").strip(): return row timestamp = now() plan = _parse_json(row.get("plan_json"), {}) governance = _parse_json(row.get("governance_json"), {}) oneliner_profile_version = ( governance.get("oneliner_profile_version") or (governance.get("oneliner_profile") or {}).get("current_version") or {} ) platform_agent_profile = governance.get("platform_agent_profile") or {} steps = [str(item).strip() for item in list(plan.get("steps") or []) if str(item).strip()] if not steps: steps = ["读取当前项目上下文", "结合治理层生成执行计划", "收口为可执行建议"] summary_text = str(plan.get("summary") or row.get("summary") or "").strip() or "主 Agent 已根据当前计划完成第一版执行收口。" execution_summary = f"已完成「{str(plan.get('goal') or row.get('title') or '主 Agent 任务').strip() or '主 Agent 任务'}」的首轮执行建议。" recommended_action = _build_agent_run_recommended_action(row, plan) result_sections = _build_agent_run_result_sections(row, plan, recommended_action) result_payload = { "result_kind": "main_agent_plan", "run_id": run_id, "goal": str(plan.get("goal") or row.get("title") or "主 Agent 任务").strip() or "主 Agent 任务", "summary_text": summary_text, "execution_summary": execution_summary, "next_steps": steps, "intent_key": str(plan.get("intent_key") or row.get("intent_key") or "custom").strip() or "custom", "platform": str(plan.get("platform") or row.get("platform") or "").strip(), "platform_scope": str(plan.get("platform_scope") or row.get("platform_scope") or "single_platform").strip() or "single_platform", "recommended_action": recommended_action, "result_sections": result_sections, "active_admin_override_notice": _parse_json(row.get("active_admin_override_notice_json"), {}), "execution_card": { "intent_key": str(plan.get("intent_key") or row.get("intent_key") or "custom").strip() or "custom", "intent_label": str(plan.get("intent_label") or "").strip() or "主 Agent 任务", "delivery_mode": str(plan.get("delivery_mode") or row.get("delivery_mode") or "oneliner").strip() or "oneliner", "platform": str(plan.get("platform") or row.get("platform") or "").strip(), "platform_label": str(plan.get("platform_label") or "").strip() or "待判断", "active_admin_override_notice": _parse_json(row.get("active_admin_override_notice_json"), {}), "oneliner_profile_version": { "version_id": str(oneliner_profile_version.get("id") or "").strip(), "version_no": int(oneliner_profile_version.get("version_no") or 0), "title": str(oneliner_profile_version.get("title") or "").strip(), "summary": str(oneliner_profile_version.get("summary") or "").strip(), }, "platform_agent_profile": { "platform": str(platform_agent_profile.get("platform") or "").strip(), "platform_label": str(platform_agent_profile.get("platform_label") or "").strip(), "name": str(platform_agent_profile.get("name") or "").strip(), "assistant_name": str(platform_agent_profile.get("assistant_name") or "").strip(), "version_id": str(((platform_agent_profile.get("current_version") or {}).get("id") or "").strip()), "version_no": int(((platform_agent_profile.get("current_version") or {}).get("version_no") or 0)), "version_title": str(((platform_agent_profile.get("current_version") or {}).get("title") or "").strip()), "version_summary": str(((platform_agent_profile.get("current_version") or {}).get("summary") or "").strip()), "mission": str(platform_agent_profile.get("mission") or "").strip(), "status": str(platform_agent_profile.get("status") or "").strip(), "readiness_label": str(platform_agent_profile.get("readiness_label") or "").strip(), "readiness_score": int(platform_agent_profile.get("readiness_score") or 0), }, "next_steps": steps, }, } _log_agent_run_event( run_id, event_type="run.progress", summary="主 Agent 已完成首轮分析,正在收口执行建议", details={"completed_steps": len(steps), "total_steps": len(steps)}, ) legacy.db.execute( """ UPDATE agent_runs SET run_status = 'done', status_summary = ?, result_json = ?, needs_user_input = 0, blocked_reason = '', updated_at = ?, finished_at = ? WHERE id = ? """, (execution_summary, _dump(result_payload), timestamp, timestamp, run_id), ) _record_platform_agent_execution_feedback( str(row.get("user_id") or "").strip(), project_id=str(row.get("project_id") or "").strip(), platform=str(row.get("platform") or "").strip(), run_id=run_id, run_status="done", intent_key=str(plan.get("intent_key") or row.get("intent_key") or "custom").strip() or "custom", source_screen=str(row.get("source_screen") or "").strip(), oneliner_profile_version_no=int(oneliner_profile_version.get("version_no") or 0), platform_agent_profile_version_no=int(((platform_agent_profile.get("current_version") or {}).get("version_no") or 0)), execution_summary=execution_summary, ) _log_agent_run_event( run_id, event_type="run.done", summary=execution_summary, details={"result_kind": "main_agent_plan", "status_summary": execution_summary}, ) refreshed = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (run_id,)) return refreshed or row def _deterministic_intent(message: str, platform_hint: str, account: dict[str, Any]) -> dict[str, Any]: text = message.strip() lowered = text.lower() platform = normalize_platform_from_text(text) or _safe_platform(platform_hint or "", fallback="") intent_key = "custom" confidence = 0.45 summary = "先理解目标,再把任务路由到合适的平台 Agent 或固定能力。" if any(keyword in text for keyword in ("新建项目", "创建项目", "建项目")): intent_key = "create_project" confidence = 0.96 summary = "这是一个新项目启动诉求,优先进入项目创建流。" elif any(keyword in lowered for keyword in ("create agent",)) or any(keyword in text for keyword in ("创建agent", "创建 Agent", "新建agent", "新建 Agent")): intent_key = "create_assistant" confidence = 0.96 summary = "这是定义新 Agent 的需求,适合直接进入 Agent 创建流。" elif any(keyword in text for keyword in ("导入主页", "主页链接", "账号主页", "主页账号")): intent_key = "import_homepage" confidence = 0.9 summary = "这是账号主页导入诉求,适合进入内容源接入。" elif any(keyword in text for keyword in ("跟踪", "日报", "更新提醒", "持续跟")): intent_key = "track_account" confidence = 0.9 summary = "这是持续跟踪类任务,适合交给平台 Agent 和跟踪摘要链。" elif any(keyword in text for keyword in ("高分", "爆款", "优质作品", "高表现")): intent_key = "analyze_top_videos" confidence = 0.88 summary = "这是高表现内容拆解诉求,优先分析高分作品。" elif any(keyword in text for keyword in ("对标", "分析账号", "调研", "拆账号")): intent_key = "analyze_account" confidence = 0.86 summary = "这是账号层面的调研任务,优先交给对应平台 Agent。" elif any(keyword in text for keyword in ("文案", "脚本", "口播", "改写")): intent_key = "generate_copy" confidence = 0.88 summary = "这是文案/脚本生成任务,适合走 Agent 生成链。" elif any(keyword in text for keyword in ("AI视频", "AI 视频", "生成视频")): intent_key = "ai_video" confidence = 0.9 summary = "这是 AI 视频生产任务,适合走 AI 视频链。" elif any(keyword in text for keyword in ("实拍", "剪辑", "混剪")): intent_key = "real_cut" confidence = 0.9 summary = "这是实拍剪辑任务,适合走 cutvideo 链。" elif any(keyword in text for keyword in ("直播", "录制", "开录")): intent_key = "live_recorder" confidence = 0.9 summary = "这是直播录制任务,适合走 NAS 录制能力。" elif any(keyword in text for keyword in ("复盘", "发布总结", "回看数据")): intent_key = "review" confidence = 0.84 summary = "这是发布复盘任务,适合进入复盘工作台。" elif any(keyword in text for keyword in ("空间", "缓存", "存储", "NAS")): intent_key = "storage_status" confidence = 0.82 summary = "这是存储状态问题,适合查看租户存储面板。" elif account.get("role") == "super_admin" and any(keyword in text for keyword in ("报错", "日志", "故障", "运维", "修复")): intent_key = "ops_admin" confidence = 0.84 summary = "这是平台级运维诉求,只能交给管理员运维/审计能力。" return { "intent_key": intent_key, "platform": platform or "", "confidence": confidence, "summary": summary, "reasoning_mode": "deterministic-first", } def normalize_platform_from_text(text: str) -> str: for key, value in legacy.PLATFORM_ALIASES.items(): if key and key in text.lower(): if value in legacy.DOMESTIC_PLATFORMS: return value for key, value in legacy.PLATFORM_ALIASES.items(): if key and key in text: if value in legacy.DOMESTIC_PLATFORMS: return value return "" async def _model_refine_intent( account: dict[str, Any], *, project_id: str, message: str, platform_hint: str, ) -> dict[str, Any]: profile = legacy.model_profile_for_account(account["id"], None) if not profile: raise HTTPException(status_code=503, detail="No model profile available") system_prompt = ( "你是 StoryForge 的 OneLiner 总控主Agent,只负责把用户目标分类成安全的系统动作。" "必须输出 JSON,不要输出 Markdown。" ) user_prompt = ( f"用户角色:{account.get('role','user')}\n" f"项目:{project_id or '默认项目'}\n" f"平台提示:{platform_hint or '未指定'}\n" f"用户原话:{message}\n\n" "请输出 JSON:" "{" '"intent_key":"","platform":"","confidence":0.0,' '"summary":"","needs_oneliner_only":false,' '"remember_preference":false' "}\n" "intent_key 只能取:create_project, create_assistant, import_homepage, track_account, analyze_account, analyze_top_videos, generate_copy, ai_video, real_cut, review, live_recorder, storage_status, ops_admin, custom。" "如果前端 UI 还没有明确产品化,needs_oneliner_only 返回 true。" ) raw = await legacy.call_model(profile, system_prompt, user_prompt, temperature=0.1) parsed = legacy.parse_json_object(raw) if not parsed: raise HTTPException(status_code=502, detail="OneLiner planner returned empty result") return { "intent_key": str(parsed.get("intent_key") or "custom").strip() or "custom", "platform": normalize_platform_from_text(str(parsed.get("platform") or "")) or _safe_platform(platform_hint or "", fallback=""), "confidence": float(parsed.get("confidence") or 0), "summary": str(parsed.get("summary") or "").strip() or "已按模型判断用户目标。", "needs_oneliner_only": bool(parsed.get("needs_oneliner_only")), "remember_preference": bool(parsed.get("remember_preference")), "reasoning_mode": "model-refine", } async def _plan_oneliner_request( account: dict[str, Any], *, project_id: str, message: str, platform_hint: str, ) -> dict[str, Any]: plan = _deterministic_intent(message, platform_hint, account) if plan["confidence"] < 0.82: try: refined = await _model_refine_intent(account, project_id=project_id, message=message, platform_hint=platform_hint) if refined.get("confidence", 0) >= plan.get("confidence", 0): plan = {**plan, **refined} except Exception: pass intent_key = plan.get("intent_key") or "custom" actions = INTENT_ACTIONS.get(intent_key, []) if intent_key == "ops_admin" and account.get("role") != "super_admin": actions = [] plan["summary"] = "这是平台级运维诉求,但当前账号没有管理员权限。" plan["needs_oneliner_only"] = True ui_supported = bool(actions) if intent_key == "custom": plan["needs_oneliner_only"] = True plan["ui_supported"] = ui_supported plan["delivery_mode"] = "ui" if ui_supported and not plan.get("needs_oneliner_only") else "oneliner" plan["suggested_actions"] = actions plan["intent_label"] = INTENT_LABELS.get(intent_key, intent_key) plan["platform_label"] = legacy.platform_label(plan.get("platform")) if plan.get("platform") else "待判断" plan["economicity"] = { "policy": "deterministic-first", "explanation": "先走固定流程,再走平台 Agent,最后才升级到 OneLiner 深度调度。", } return plan def _remember_message_preference( account: dict[str, Any], *, project_id: str, plan: dict[str, Any], message: str, ) -> dict[str, Any] | None: cues = ("记住", "以后", "长期", "默认", "一直", "优先") if not plan.get("remember_preference") and not any(cue in message for cue in cues): return None agent_scope = "oneliner" platform = plan.get("platform") or "" subject_type = "project" if project_id else "account" subject_id = project_id or account["id"] memory_key = f"preference::{plan.get('intent_key') or 'custom'}" existing = legacy.db.fetch_one( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = ? AND platform = ? AND subject_type = ? AND subject_id = ? AND memory_key = ? """, (account["id"], project_id, agent_scope, platform, subject_type, subject_id, memory_key), ) timestamp = now() details = { "captured_from": "oneliner_chat", "intent_key": plan.get("intent_key", "custom"), "source_message": message, "platform": platform, } if existing: legacy.db.execute( """ UPDATE agent_memories SET title = ?, summary = ?, details_json = ?, confidence = ?, last_validated_at = ?, updated_at = ? WHERE id = ? """, ( f"{INTENT_LABELS.get(plan.get('intent_key') or 'custom', '偏好')}偏好", message.strip()[:280], _dump(details), 0.82, timestamp, timestamp, existing["id"], ), ) stored = legacy.db.fetch_one("SELECT * FROM agent_memories WHERE id = ?", (existing["id"],)) else: memory_id = make_id("mem") legacy.db.execute( """ INSERT INTO agent_memories ( id, user_id, project_id, agent_scope, platform, subject_type, subject_id, memory_key, title, summary, details_json, confidence, last_validated_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( memory_id, account["id"], project_id, agent_scope, platform, subject_type, subject_id, memory_key, f"{INTENT_LABELS.get(plan.get('intent_key') or 'custom', '偏好')}偏好", message.strip()[:280], _dump(details), 0.82, timestamp, timestamp, timestamp, ), ) stored = legacy.db.fetch_one("SELECT * FROM agent_memories WHERE id = ?", (memory_id,)) return _memory_payload(stored) if stored else None def _remember_platform_observation( account: dict[str, Any], *, project_id: str, platform: str, memory_key: str, title: str, summary: str, details: dict[str, Any], confidence: float = 0.82, ) -> dict[str, Any]: request = AgentMemoryUpsertRequest( project_id=project_id, subject_type="project", subject_id=project_id, memory_key=memory_key, title=title, summary=summary, details=details, confidence=confidence, ) return _upsert_memory(account, agent_scope="platform", platform=platform, request=request) def _session_context_summary(account: dict[str, Any], project_id: str, platform: str) -> dict[str, Any]: project = _resolve_project(account, project_id or None) assistant = None profile_row = _fetch_profile_row(account, project["id"]) if profile_row and profile_row.get("assistant_id"): assistant = _resolve_assistant(account, profile_row.get("assistant_id"), project["id"]) platform_profile = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], platform), ) if platform else None oneliner_memory_rows = legacy.db.fetch_all( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = 'oneliner' ORDER BY updated_at DESC LIMIT 3 """, (account["id"], project["id"]), ) platform_memory_rows = legacy.db.fetch_all( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY updated_at DESC LIMIT 3 """, (account["id"], project["id"], platform), ) if platform else [] platform_skill_rows = legacy.db.fetch_all( """ SELECT * FROM agent_skills WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY CASE WHEN status = 'validated' THEN 0 WHEN status = 'draft' THEN 1 ELSE 2 END, updated_at DESC LIMIT 3 """, (account["id"], project["id"], platform), ) if platform else [] governance_effective = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform=platform, ) user_global_scope = _policy_scope_row( scope_kind="user_global", subject_user_id=account["id"], subject_project_id=project["id"], ) user_platform_scope = _policy_scope_row( scope_kind="user_platform", subject_user_id=account["id"], subject_project_id=project["id"], platform=_normalize_policy_platform(platform), ) if platform else None return { "project": legacy.project_payload(project), "oneliner_profile": _oneliner_profile_bundle(profile_row, account=account) if profile_row else None, "platform_agent": _platform_agent_payload(account, platform_profile, platform=platform, project_id=project["id"]) if platform else None, "assistant": legacy.assistant_payload(assistant) if assistant else None, "oneliner_memories": [_memory_payload(row) for row in oneliner_memory_rows], "platform_memories": [_memory_payload(row) for row in platform_memory_rows], "platform_skills": [_skill_payload(row) for row in platform_skill_rows], "governance": { "effective": governance_effective, "user_global": _bundle_with_versions( user_global_scope, fallback_kind="user_global", fallback_user_id=account["id"], fallback_project_id=project["id"], active_version_only=True, ), "user_platform": _bundle_with_versions( user_platform_scope, fallback_kind="user_platform", fallback_platform=_normalize_policy_platform(platform), fallback_user_id=account["id"], fallback_project_id=project["id"], active_version_only=True, ) if platform else None, }, } async def _generate_oneliner_reply( account: dict[str, Any], *, project_id: str, message: str, plan: dict[str, Any], ) -> dict[str, Any]: context = _session_context_summary(account, project_id or "", plan.get("platform") or "") oneliner_profile = context.get("oneliner_profile") or {} platform_agent = context.get("platform_agent") or {} platform_agent_assistant = platform_agent.get("assistant") or {} context_assistant = context.get("assistant") or {} governance = context.get("governance") or {} effective_policy = (governance.get("effective") or {}).get("effective_policy") or {} governance_layers = (governance.get("effective") or {}).get("layers") or [] active_admin_override_notice = (governance.get("effective") or {}).get("active_admin_override_notice") or {} primary_action = (plan.get("suggested_actions") or [{}])[0] if plan.get("suggested_actions") else None evidence = [] if platform_agent.get("recent_memory"): evidence.append( { "kind": "memory", "title": platform_agent["recent_memory"].get("title") or platform_agent["recent_memory"].get("memory_key") or "最近记忆", "summary": platform_agent["recent_memory"].get("summary", ""), } ) if platform_agent.get("recent_skill"): evidence.append( { "kind": "skill", "title": platform_agent["recent_skill"].get("name") or platform_agent["recent_skill"].get("skill_key") or "最近技能", "summary": platform_agent["recent_skill"].get("test_spec", {}).get("summary") or platform_agent["recent_skill"].get("method", {}).get("summary") or "", "score": platform_agent["recent_skill"].get("last_score", 0), } ) blocked_reason = "" if plan.get("intent_key") == "ops_admin" and account.get("role") != "super_admin": blocked_reason = "当前账号不是平台最高权限用户,所以不会开放运维 Agent。" elif plan.get("delivery_mode") == "oneliner": blocked_reason = "当前更适合由 OneLiner 对话承接,等前端产品化后再下沉到固定 UI。" next_steps = [] if primary_action: next_steps.append(f"优先执行「{primary_action.get('label', primary_action.get('key', '下一步'))}」。") if platform_agent_assistant.get("name"): next_steps.append(f"默认调度 {platform_agent_assistant.get('name')} 作为执行 Agent。") if evidence: next_steps.append("我会优先参考该平台 Agent 最近沉淀的方法与技能。") if governance_layers: next_steps.append(f"当前会话已叠加 {len(governance_layers)} 层策略,我会先按生效策略执行。") if active_admin_override_notice.get("title"): next_steps.append(f"当前存在管理员覆盖:{active_admin_override_notice.get('title')}。") oneliner_profile_version = oneliner_profile.get("current_version") or {} if oneliner_profile_version.get("version_no"): next_steps.append(f"当前主 Agent 配置版本:v{oneliner_profile_version.get('version_no')}。") summary_lines = [ f"我理解你的目标是:{plan.get('intent_label', '自定义任务')}。", f"建议优先处理的平台:{plan.get('platform_label', '待判断')}。", plan.get("summary", ""), ] if plan.get("delivery_mode") == "oneliner": summary_lines.append("这项能力当前更适合先由 OneLiner 对话承接,而不是要求你先理解前端功能树。") if plan.get("intent_key") == "ops_admin" and account.get("role") != "super_admin": summary_lines.append("当前账号不是平台最高权限用户,所以我不会放出运维 Agent 入口。") if context.get("platform_agent"): summary_lines.append(f"当前 {context['platform_agent']['platform_label']} Agent 已绑定:{platform_agent_assistant.get('name') or '未绑定执行 Agent'}。") if platform_agent.get("recent_memory"): summary_lines.append(f"最近有效经验:{platform_agent['recent_memory'].get('title') or '一条平台记忆'}。") if platform_agent.get("recent_skill"): summary_lines.append(f"最近有效技能:{platform_agent['recent_skill'].get('name') or '一条技能'}。") if effective_policy.get("guardrails", {}).get("require_admin_review"): summary_lines.append("当前策略层要求管理员复核,所以我会把高风险动作先压成待确认。") if active_admin_override_notice.get("title"): summary_lines.append(f"管理员覆盖生效中:{active_admin_override_notice.get('title')}。") if oneliner_profile_version.get("version_no"): summary_lines.append(f"当前主 Agent 正在按配置版本 v{oneliner_profile_version.get('version_no')} 执行。") secondary_actions: list[dict[str, Any]] = [] if plan.get("platform"): secondary_actions.append( { "key": "run-oneliner-action", "label": "运行平台自检", "kind": "api_action", "executor_key": "platform-self-check", "platform": plan.get("platform", ""), } ) secondary_actions.append( { "key": "open-platform-agent-detail", "label": f"查看{plan.get('platform_label', '平台')} Agent", "kind": "ui_action", "platform": plan.get("platform", ""), } ) first_url = _extract_first_url(message) if plan.get("intent_key") in {"import_homepage", "custom"} and first_url: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接导入主页", "kind": "api_action", "executor_key": "import-homepage", "platform": plan.get("platform", ""), "payload": { "source_url": first_url, }, } ) if plan.get("intent_key") in {"storage_status", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "查看当前存储状态", "kind": "api_action", "executor_key": "storage-status", "platform": plan.get("platform", ""), } ) if plan.get("intent_key") == "live_recorder": secondary_actions.append( { "key": "run-oneliner-action", "label": "查看录制状态", "kind": "api_action", "executor_key": "live-recorder-status", "platform": plan.get("platform", ""), } ) if first_url: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接保存录制源", "kind": "api_action", "executor_key": "save-live-recorder-source", "platform": plan.get("platform", ""), "payload": { "source_url": first_url, "auto_start": True, }, } ) latest_platform_account = None if plan.get("platform"): latest_platform_account = _latest_platform_account( account, project_id=project_id or "", platform=plan.get("platform", ""), ) if plan.get("platform") and latest_platform_account and plan.get("intent_key") in {"analyze_top_videos", "analyze_account", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接分析账号", "kind": "api_action", "executor_key": "analyze-account", "platform": plan.get("platform", ""), "payload": { "target_account_id": latest_platform_account["id"], }, } ) secondary_actions.append( { "key": "run-oneliner-action", "label": "直接分析高分作品", "kind": "api_action", "executor_key": "analyze-top-videos", "platform": plan.get("platform", ""), "payload": { "target_account_id": latest_platform_account["id"], }, } ) secondary_actions.append( { "key": "run-oneliner-action", "label": "直接查相似账号", "kind": "api_action", "executor_key": "search-similar-accounts", "platform": plan.get("platform", ""), "payload": { "target_account_id": latest_platform_account["id"], }, } ) if plan.get("platform") and latest_platform_account and plan.get("intent_key") in {"track_account", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接加入跟踪", "kind": "api_action", "executor_key": "track-account", "platform": plan.get("platform", ""), "payload": { "target_account_id": latest_platform_account["id"], "refresh_now": True, }, } ) latest_similarity = ( _latest_similarity_candidate( account, platform=plan.get("platform", ""), source_account_id=latest_platform_account["id"], ) if plan.get("platform") and latest_platform_account else None ) latest_similarity_candidate = (latest_similarity or {}).get("candidate") or {} if ( plan.get("platform") and latest_platform_account and latest_similarity_candidate and plan.get("intent_key") in {"analyze_top_videos", "analyze_account", "custom", "track_account"} ): secondary_actions.append( { "key": "run-oneliner-action", "label": "直接存对标关系", "kind": "api_action", "executor_key": "save-benchmark-link", "platform": plan.get("platform", ""), "payload": { "source_account_id": latest_platform_account["id"], "target_account_id": latest_similarity_candidate.get("candidate_account_id") or "", "target_profile_url": latest_similarity_candidate.get("candidate_profile_url") or "", "search_id": (latest_similarity or {}).get("search_id") or "", }, } ) if plan.get("platform") and plan.get("intent_key") in {"track_account", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接同步跟踪池", "kind": "api_action", "executor_key": "refresh-tracking", "platform": plan.get("platform", ""), } ) secondary_actions.append( { "key": "run-oneliner-action", "label": "直接标记日报已读", "kind": "api_action", "executor_key": "mark-tracking-read", "platform": plan.get("platform", ""), } ) if context_assistant: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接生成一版文案", "kind": "api_action", "executor_key": "generate-copy", "platform": plan.get("platform", ""), } ) if not context_assistant and plan.get("intent_key") in {"create_assistant", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接创建 Agent", "kind": "api_action", "executor_key": "create-assistant", "platform": plan.get("platform", ""), "payload": { "name": plan.get("platform_label") and f"{plan.get('platform_label')} 执行 Agent" or "项目执行 Agent", }, } ) latest_job = _latest_project_job(account, project_id=project_id or "") if latest_job: secondary_actions.append( { "key": "run-oneliner-action", "label": "生成复盘草稿", "kind": "api_action", "executor_key": "review-draft", "platform": plan.get("platform", ""), } ) derivable_job = _latest_derivable_job(account, project_id=project_id or "", exclude_line_types={"ai_video", "real_cut"}) if derivable_job and plan.get("intent_key") in {"ai_video", "real_cut", "review", "custom"}: secondary_actions.append( { "key": "run-oneliner-action", "label": "直接创建 AI 视频", "kind": "api_action", "executor_key": "create-ai-video", "platform": plan.get("platform", ""), "payload": { "source_job_id": derivable_job["id"], }, } ) secondary_actions.append( { "key": "run-oneliner-action", "label": "直接创建实拍剪辑", "kind": "api_action", "executor_key": "create-real-cut", "platform": plan.get("platform", ""), "payload": { "source_job_id": derivable_job["id"], }, } ) if account.get("role") == "super_admin": secondary_actions.append( { "key": "run-oneliner-action", "label": "重新扫描故障", "kind": "api_action", "executor_key": "scan-admin-ops", "platform": "", } ) decorated_primary_action = _decorate_oneliner_action( account, project_id=project_id or "", action=primary_action or {}, ) if primary_action else {} secondary_actions = [ _decorate_oneliner_action(account, project_id=project_id or "", action=item) for item in secondary_actions ] return { "summary_text": "\n".join([line for line in summary_lines if line.strip()]), "context": context, "execution_card": { "intent_key": plan.get("intent_key", "custom"), "intent_label": plan.get("intent_label", "自定义任务"), "delivery_mode": plan.get("delivery_mode", "oneliner"), "platform": plan.get("platform", ""), "platform_label": plan.get("platform_label", "待判断"), "platform_agent_name": platform_agent.get("name") or "", "assistant_name": platform_agent_assistant.get("name") or context_assistant.get("name") or "", "readiness_label": platform_agent.get("readiness_label") or "", "readiness_score": platform_agent.get("readiness_score") or 0, "primary_action": decorated_primary_action, "blocked_reason": blocked_reason, "active_admin_override_notice": active_admin_override_notice, "oneliner_profile_version": { "version_id": oneliner_profile_version.get("id", ""), "version_no": oneliner_profile_version.get("version_no", 0), "title": oneliner_profile_version.get("title", ""), "summary": oneliner_profile_version.get("summary", ""), }, "platform_agent_profile": { "platform": platform_agent.get("platform") or plan.get("platform", ""), "platform_label": platform_agent.get("platform_label") or plan.get("platform_label", ""), "name": platform_agent.get("name", ""), "assistant_name": platform_agent_assistant.get("name") or context_assistant.get("name") or "", "version_id": ((platform_agent.get("current_version") or {}).get("id") or ""), "version_no": ((platform_agent.get("current_version") or {}).get("version_no") or 0), "readiness_label": platform_agent.get("readiness_label") or "", "readiness_score": platform_agent.get("readiness_score") or 0, }, "evidence": evidence, "next_steps": next_steps, "secondary_actions": secondary_actions, }, "safe_boundary": { "core_code_locked": True, "tenant_isolation": True, "ops_admin_only": True, }, } def _insert_message(session_id: str, account_id: str, role: str, content: str, plan: dict[str, Any], result: dict[str, Any]) -> dict[str, Any]: message_id = make_id("oline_msg") created_at = now() legacy.db.execute( """ INSERT INTO oneliner_messages (id, session_id, user_id, role, content, plan_json, result_json, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) """, (message_id, session_id, account_id, role, content, _dump(plan), _dump(result), created_at), ) return legacy.db.fetch_one("SELECT * FROM oneliner_messages WHERE id = ?", (message_id,)) def _upsert_platform_profile(account: dict[str, Any], platform: str, request: PlatformAgentProfileRequest) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) assistant = _resolve_assistant(account, request.assistant_id or None, project["id"]) if not assistant: fallback_profile = _fetch_profile_row(account, project["id"]) or _ensure_oneliner_profile(account, project["id"]) if fallback_profile.get("assistant_id"): assistant = _resolve_assistant(account, fallback_profile.get("assistant_id"), project["id"]) if not assistant: assistant = _resolve_assistant(account, None, project["id"]) existing = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], platform), ) timestamp = now() resolved_assistant_id = (assistant or {}).get("id", "") if existing: update_sql = """ UPDATE platform_agent_profiles SET assistant_id = ?, name = ?, mission = ?, notes = ?, status = ?, config_json = ?, updated_at = ? WHERE id = ? """ update_params = ( resolved_assistant_id, request.name.strip() or existing.get("name") or f"{legacy.platform_label(platform)} Agent", request.mission.strip(), request.notes.strip(), request.status.strip() or "active", _dump(request.config), timestamp, existing["id"], ) if resolved_assistant_id: legacy.db.execute(update_sql, update_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(update_sql, update_params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM platform_agent_profiles WHERE id = ?", (existing["id"],)) else: profile_id = make_id("plat_agent") insert_sql = """ INSERT INTO platform_agent_profiles ( id, user_id, project_id, platform, assistant_id, name, mission, notes, status, config_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """ insert_params = ( profile_id, account["id"], project["id"], platform, resolved_assistant_id, request.name.strip() or f"{legacy.platform_label(platform)} Agent", request.mission.strip(), request.notes.strip(), request.status.strip() or "active", _dump(request.config), timestamp, timestamp, ) if resolved_assistant_id: legacy.db.execute(insert_sql, insert_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(insert_sql, insert_params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM platform_agent_profiles WHERE id = ?", (profile_id,)) assert row is not None version = _create_platform_agent_profile_version( row, actor_user_id=account["id"], source_type="user_update", reason=request.reason.strip() or f"更新 {legacy.platform_label(platform)} Agent 配置", ) _log_platform_agent_profile_audit( profile_id=row["id"], version_id=version["id"], actor_user_id=account["id"], action_key="update-platform-agent-profile", summary=f"已更新 {legacy.platform_label(platform)} Agent 配置", details={"project_id": project["id"], "platform": platform, "assistant_id": row.get("assistant_id", "")}, ) return _platform_agent_payload(account, row, platform=platform, project_id=project["id"]) def _upsert_memory( account: dict[str, Any], *, agent_scope: str, platform: str, request: AgentMemoryUpsertRequest, ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) subject_type = request.subject_type.strip() or "project" subject_id = request.subject_id.strip() or (project["id"] if subject_type == "project" else account["id"]) existing = legacy.db.fetch_one( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = ? AND platform = ? AND subject_type = ? AND subject_id = ? AND memory_key = ? """, (account["id"], project["id"], agent_scope, platform, subject_type, subject_id, request.memory_key.strip()), ) timestamp = now() if existing: legacy.db.execute( """ UPDATE agent_memories SET title = ?, summary = ?, details_json = ?, confidence = ?, last_validated_at = ?, updated_at = ? WHERE id = ? """, ( request.title.strip(), request.summary.strip(), _dump(request.details), request.confidence, timestamp, timestamp, existing["id"], ), ) row = legacy.db.fetch_one("SELECT * FROM agent_memories WHERE id = ?", (existing["id"],)) else: memory_id = make_id("mem") legacy.db.execute( """ INSERT INTO agent_memories ( id, user_id, project_id, agent_scope, platform, subject_type, subject_id, memory_key, title, summary, details_json, confidence, last_validated_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( memory_id, account["id"], project["id"], agent_scope, platform, subject_type, subject_id, request.memory_key.strip(), request.title.strip(), request.summary.strip(), _dump(request.details), request.confidence, timestamp, timestamp, timestamp, ), ) row = legacy.db.fetch_one("SELECT * FROM agent_memories WHERE id = ?", (memory_id,)) return _memory_payload(row) def _upsert_skill( account: dict[str, Any], *, agent_scope: str, platform: str, request: AgentSkillUpsertRequest, skill_id: str | None = None, ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) existing = None if skill_id: existing = legacy.db.fetch_one( "SELECT * FROM agent_skills WHERE id = ? AND user_id = ?", (skill_id, account["id"]), ) if not existing: raise HTTPException(status_code=404, detail="Agent skill not found") else: existing = legacy.db.fetch_one( """ SELECT * FROM agent_skills WHERE user_id = ? AND project_id = ? AND agent_scope = ? AND platform = ? AND skill_key = ? """, (account["id"], project["id"], agent_scope, platform, request.skill_key.strip()), ) timestamp = now() if existing: legacy.db.execute( """ UPDATE agent_skills SET name = ?, status = ?, method_json = ?, test_spec_json = ?, last_result_json = ?, success_count = ?, failure_count = ?, last_score = ?, last_validated_at = ?, updated_at = ? WHERE id = ? """, ( request.name.strip(), request.status.strip() or "draft", _dump(request.method), _dump(request.test_spec), _dump(request.last_result), request.success_count, request.failure_count, request.last_score, timestamp, timestamp, existing["id"], ), ) row = legacy.db.fetch_one("SELECT * FROM agent_skills WHERE id = ?", (existing["id"],)) _snapshot_skill_version( row, actor_user_id=account["id"], reason="updated", metadata={"via": "upsert", "accepted": row.get("status") == "validated"}, ) else: new_id = make_id("skill") legacy.db.execute( """ INSERT INTO agent_skills ( id, user_id, project_id, agent_scope, platform, parent_skill_id, skill_key, name, status, method_json, test_spec_json, last_result_json, success_count, failure_count, last_score, last_validated_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, '', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( new_id, account["id"], project["id"], agent_scope, platform, request.skill_key.strip(), request.name.strip(), request.status.strip() or "draft", _dump(request.method), _dump(request.test_spec), _dump(request.last_result), request.success_count, request.failure_count, request.last_score, timestamp, timestamp, timestamp, ), ) row = legacy.db.fetch_one("SELECT * FROM agent_skills WHERE id = ?", (new_id,)) _snapshot_skill_version( row, actor_user_id=account["id"], reason="created", metadata={"via": "upsert"}, ) return _skill_payload(row) def _create_or_update_incident( *, tenant_user_id: str, tenant_project_id: str, source_type: str, source_id: str, severity: str, title: str, summary: str, payload: dict[str, Any], ) -> dict[str, Any]: existing = legacy.db.fetch_one( "SELECT * FROM admin_ops_incidents WHERE source_type = ? AND source_id = ? AND title = ?", (source_type, source_id, title), ) timestamp = now() disable_fk = not str(tenant_user_id or "").strip() or not str(tenant_project_id or "").strip() if existing: sql = """ UPDATE admin_ops_incidents SET tenant_user_id = ?, tenant_project_id = ?, severity = ?, summary = ?, payload_json = ?, updated_at = ? WHERE id = ? """ params = ( tenant_user_id, tenant_project_id, severity, summary, _dump(payload), timestamp, existing["id"], ) if disable_fk: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(sql, params) conn.execute("PRAGMA foreign_keys=ON") else: legacy.db.execute(sql, params) row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (existing["id"],)) else: incident_id = make_id("incident") sql = """ INSERT INTO admin_ops_incidents ( id, tenant_user_id, tenant_project_id, source_type, source_id, severity, title, summary, payload_json, status, assigned_to, reviewed_by, review_notes, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', '', '', '', ?, ?) """ params = ( incident_id, tenant_user_id, tenant_project_id, source_type, source_id, severity, title, summary, _dump(payload), timestamp, timestamp, ) with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(sql, params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (incident_id,)) return _incident_payload(row) def _scan_admin_incidents(admin: dict[str, Any]) -> dict[str, Any]: _ = admin created: list[dict[str, Any]] = [] failed_jobs = legacy.db.fetch_all( "SELECT * FROM jobs WHERE status = 'failed' ORDER BY updated_at DESC LIMIT 20" ) for job in failed_jobs: created.append( _create_or_update_incident( tenant_user_id=job.get("user_id", "") or "", tenant_project_id=job.get("project_id", "") or "", source_type="job", source_id=job["id"], severity="error", title=f"失败任务:{job.get('title') or job['id']}", summary=job.get("error", "")[:280] or "任务失败,需要检查执行链。", payload=legacy.job_payload(job), ) ) try: integration_health = legacy.integrations_health(admin) except Exception as exc: integration_health = {"collector": {"reachable": False, "error": str(exc)}} for key, payload in integration_health.items(): reachable = bool(payload.get("reachable", False)) if reachable and key != "cutvideo": continue if key == "cutvideo" and payload.get("supports_uploads", True): continue created.append( _create_or_update_incident( tenant_user_id="", tenant_project_id="", source_type="integration", source_id=key, severity="warn" if key in {"cutvideo", "live_recorder"} else "error", title=f"集成异常:{key}", summary=str(payload.get("error") or payload.get("upload_error") or "集成健康检查未通过")[:280], payload=payload, ) ) return { "created_or_updated": created, "count": len(created), "audit": _log_admin_audit_event( actor_user_id=admin["id"], action_key="scan", status="completed", summary=f"本轮扫描归集 {len(created)} 条事件。", details={"count": len(created)}, ), } def _build_incident_repair_plan( incident: dict[str, Any], *, scope: str, notes: str, ) -> dict[str, Any]: payload = incident.get("payload") or {} source_type = incident.get("source_type") or "" severity = incident.get("severity") or "warn" if source_type == "integration": target = incident.get("source_id") or "integration" steps = [ f"读取 {target} 当前健康状态和最近错误详情。", f"对 {target} 执行最小可行 smoke,确认是网络、配置还是服务端版本问题。", "若为外部依赖异常,则先生成修复建议而不是直接改核心代码。", ] verification = [ "health 接口恢复可达", "关键能力 smoke 返回 200", "相关任务链不再新增 failed", ] elif source_type == "job": target = payload.get("title") or incident.get("source_id") or "job" steps = [ f"读取失败任务 {target} 的 error/result/artifacts。", "定位失败在哪个集成或哪段编排上。", "生成补救建议或重试路径,并明确是否需要人工确认。", ] verification = [ "同类任务能再次跑通", "错误不再重复出现", "租户数据和存储路径未被污染", ] else: steps = [ "读取当前事件上下文和最近变更。", "先给出低风险修复建议,再决定是否进入人工处理。", ] verification = ["事件状态可被复核", "没有破坏多租户隔离"] return { "summary": f"针对 {incident.get('title') or incident.get('id')} 生成一版{scope}级修复计划。", "severity": severity, "scope": scope, "source_type": source_type, "steps": steps, "verification": verification, "safe_boundary": { "core_code_locked": True, "tenant_isolation_required": True, "audit_required": True, }, "notes": notes.strip(), } def _create_fix_run( admin: dict[str, Any], *, incident: dict[str, Any], scope: str, notes: str, ) -> dict[str, Any]: plan = _build_incident_repair_plan(incident, scope=scope, notes=notes) run_id = make_id("fix_run") timestamp = now() disable_fk = not str(incident.get("tenant_user_id") or "").strip() or not str(incident.get("tenant_project_id") or "").strip() sql = """ INSERT INTO admin_ops_fix_runs ( id, incident_id, actor_user_id, tenant_user_id, tenant_project_id, plan_scope, status, audit_status, review_notes, plan_json, verification_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, 'planned', 'pending', '', ?, ?, ?, ?) """ params = ( run_id, incident["id"], admin["id"], incident.get("tenant_user_id", ""), incident.get("tenant_project_id", ""), scope, _dump(plan), _dump({"checks": plan.get("verification", [])}), timestamp, timestamp, ) with legacy.db.session() as conn: if disable_fk: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(sql, params) if disable_fk: conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM admin_ops_fix_runs WHERE id = ?", (run_id,)) return _fix_run_payload(row) def _admin_ops_overview_payload(admin: dict[str, Any]) -> dict[str, Any]: incidents = [ _incident_payload(row) for row in legacy.db.fetch_all( "SELECT * FROM admin_ops_incidents ORDER BY updated_at DESC LIMIT 50" ) ] open_incidents = [item for item in incidents if item.get("status") in {"open", "watching", ""}] severity_counts = { "error": len([item for item in incidents if item.get("severity") == "error"]), "warn": len([item for item in incidents if item.get("severity") == "warn"]), "info": len([item for item in incidents if item.get("severity") == "info"]), } failed_jobs = [ legacy.job_payload(row) for row in legacy.db.fetch_all( "SELECT * FROM jobs WHERE status = 'failed' ORDER BY updated_at DESC LIMIT 12" ) ] pending_accounts = [ legacy.normalize_account(row) for row in legacy.db.fetch_all("SELECT * FROM accounts WHERE approval_status = 'pending' ORDER BY created_at ASC LIMIT 20") ] recent_audits = [ _admin_audit_payload(row) for row in legacy.db.fetch_all( "SELECT * FROM admin_ops_audit_logs ORDER BY created_at DESC LIMIT 20" ) ] recent_fix_runs = [ _fix_run_payload(row) for row in legacy.db.fetch_all( "SELECT * FROM admin_ops_fix_runs ORDER BY updated_at DESC LIMIT 20" ) ] return { "incidents": incidents, "incident_count": len(incidents), "open_incident_count": len(open_incidents), "severity_counts": severity_counts, "failed_jobs": failed_jobs, "failed_job_count": len(failed_jobs), "pending_accounts": pending_accounts, "pending_account_count": len(pending_accounts), "recent_audits": recent_audits, "audit_count": len(recent_audits), "recent_fix_runs": recent_fix_runs, "fix_run_count": len(recent_fix_runs), "pending_fix_run_count": len([item for item in recent_fix_runs if item.get("audit_status") == "pending"]), "integration_health": legacy.integrations_health(admin), } def _platform_self_check( account: dict[str, Any], *, platform: str, project_id: str, sample_limit: int = 3, remember_summary: bool = True, ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) profile = _platform_agent_payload( account, legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], normalized_platform), ), platform=normalized_platform, project_id=project["id"], ) route_checks = _platform_route_checks(normalized_platform) route_ok_count = len([item for item in route_checks if item["ok"]]) route_ratio = (route_ok_count / len(route_checks)) if route_checks else 0 source_samples = _platform_source_samples(account, project_id=project["id"], platform=normalized_platform, limit=sample_limit) signal_checks = [ ("配置激活", bool(profile.get("status") == "active")), ("已绑定执行 Agent", bool(profile.get("assistant_id"))), ("已有平台记忆", bool(profile.get("memory_count"))), ("已有平台技能", bool(profile.get("skill_count"))), ("已有平台账号源", bool(source_samples)), ] signal_score = sum(1 for _, ok in signal_checks if ok) * 12 route_score = int(route_ratio * 40) score = min(100, signal_score + route_score) if score >= 85: verdict = "validated" label = "稳定" elif score >= 60: verdict = "usable" label = "可用" else: verdict = "needs_work" label = "待加强" suggestions = [] if not profile.get("assistant_id"): suggestions.append("先给平台 Agent 绑定一个执行 Agent。") if not profile.get("memory_count"): suggestions.append("补一条平台记忆,沉淀最近有效经验。") if not profile.get("skill_count"): suggestions.append("补一条可验收的平台技能。") if not source_samples: suggestions.append("先导入至少一个该平台账号源,避免空跑。") if route_ratio < 1: suggestions.append("补齐当前平台 workbench 路由,避免调度时出现断点。") payload = { "platform": normalized_platform, "platform_label": legacy.platform_label(normalized_platform), "project_id": project["id"], "score": score, "readiness_label": label, "verdict": verdict, "route_checks": route_checks, "signals": [{"label": name, "ok": ok} for name, ok in signal_checks], "source_count": len(source_samples), "source_samples": source_samples, "checked_at": now(), "suggestions": suggestions, "profile": profile, } if remember_summary: _remember_platform_observation( account, project_id=project["id"], platform=normalized_platform, memory_key=f"self_check::{normalized_platform}", title=f"{legacy.platform_label(normalized_platform)} Agent 自检", summary=f"平台自检得分 {score},当前判定为{label}。", details=payload, confidence=0.88 if score >= 85 else 0.72, ) return payload def _review_platform_skill( account: dict[str, Any], *, platform: str, skill_id: str, request: PlatformSkillReviewRequest, ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = _safe_platform(platform) current = legacy.db.fetch_one( """ SELECT * FROM agent_skills WHERE id = ? AND user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? """, (skill_id, account["id"], project["id"], normalized_platform), ) if not current: raise HTTPException(status_code=404, detail="Platform skill not found") accepted = bool(request.accepted) next_status = (request.status or "").strip() or ("validated" if accepted else "needs_revision") timestamp = now() next_success = int(current.get("success_count") or 0) + (1 if accepted else 0) next_failure = int(current.get("failure_count") or 0) + (0 if accepted else 1) result_payload = { **_parse_json(current.get("last_result_json"), {}), "accepted": accepted, "review_notes": request.review_notes.strip(), "summary": request.summary.strip(), "reviewed_at": timestamp, "reviewed_by": account["id"], } legacy.db.execute( """ UPDATE agent_skills SET status = ?, last_result_json = ?, success_count = ?, failure_count = ?, last_score = ?, last_validated_at = ?, updated_at = ? WHERE id = ? """, ( next_status, _dump(result_payload), next_success, next_failure, request.score, timestamp, timestamp, skill_id, ), ) updated = legacy.db.fetch_one("SELECT * FROM agent_skills WHERE id = ?", (skill_id,)) version = _snapshot_skill_version( updated, actor_user_id=account["id"], reason="validated" if accepted else "needs_revision", metadata={"review_notes": request.review_notes.strip(), "score": request.score}, ) feedback_summary = (request.summary or request.review_notes or "").strip() feedback_memory = None if feedback_summary: feedback_memory = _remember_platform_observation( account, project_id=project["id"], platform=normalized_platform, memory_key=f"skill_feedback::{current.get('skill_key')}", title=f"{current.get('name') or current.get('skill_key') or '技能'}·{'已验证' if accepted else '待优化'}", summary=feedback_summary[:280], details={ "skill_id": skill_id, "skill_key": current.get("skill_key", ""), "accepted": accepted, "score": request.score, "review_notes": request.review_notes.strip(), "status": next_status, }, confidence=0.9 if accepted else 0.66, ) payload = _skill_payload(updated) payload["version"] = version if feedback_memory: payload["feedback_memory"] = feedback_memory return payload def _list_skill_versions( account: dict[str, Any], *, platform: str, project_id: str, skill_id: str, ) -> list[dict[str, Any]]: skill_row = legacy.db.fetch_one( """ SELECT * FROM agent_skills WHERE id = ? AND user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? """, (skill_id, account["id"], project_id, platform), ) if not skill_row: raise HTTPException(status_code=404, detail="Platform skill not found") rows = legacy.db.fetch_all( "SELECT * FROM agent_skill_versions WHERE skill_id = ? ORDER BY version_no DESC, created_at DESC", (skill_id,), ) return [_skill_version_payload(row) for row in rows] def _rollback_platform_skill( account: dict[str, Any], *, platform: str, skill_id: str, request: PlatformSkillRollbackRequest, ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) current = legacy.db.fetch_one( """ SELECT * FROM agent_skills WHERE id = ? AND user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? """, (skill_id, account["id"], project["id"], platform), ) if not current: raise HTTPException(status_code=404, detail="Platform skill not found") target_version = legacy.db.fetch_one( """ SELECT * FROM agent_skill_versions WHERE id = ? AND skill_id = ? """, (request.version_id.strip(), skill_id), ) if not target_version: raise HTTPException(status_code=404, detail="Skill version not found") snapshot = _parse_json(target_version.get("snapshot_json"), {}) skill_snapshot = (snapshot.get("skill") or {}) timestamp = now() legacy.db.execute( """ UPDATE agent_skills SET name = ?, status = ?, method_json = ?, test_spec_json = ?, last_result_json = ?, success_count = ?, failure_count = ?, last_score = ?, last_validated_at = ?, updated_at = ? WHERE id = ? """, ( skill_snapshot.get("name") or current.get("name") or current.get("skill_key") or "平台技能", skill_snapshot.get("status") or "draft", _dump(skill_snapshot.get("method") or {}), _dump(skill_snapshot.get("test_spec") or {}), _dump(skill_snapshot.get("last_result") or {}), int(skill_snapshot.get("success_count") or 0), int(skill_snapshot.get("failure_count") or 0), float(skill_snapshot.get("last_score") or 0), skill_snapshot.get("last_validated_at") or timestamp, timestamp, skill_id, ), ) updated = legacy.db.fetch_one("SELECT * FROM agent_skills WHERE id = ?", (skill_id,)) rollback_version = _snapshot_skill_version( updated, actor_user_id=account["id"], reason="rollback", metadata={"from_version_id": request.version_id.strip()}, ) payload = _skill_payload(updated) payload["rollback_from_version"] = _skill_version_payload(target_version) payload["version"] = rollback_version return payload async def _execute_oneliner_action( account: dict[str, Any], request: OneLinerActionExecuteRequest, ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = normalize_platform_from_text(request.platform) or _safe_platform(request.platform or "", fallback="") action_key = (request.action_key or "").strip() if not action_key: raise HTTPException(status_code=400, detail="Action key is required") action_definition = _get_action_definition(account, project_id=project["id"], action_key=action_key) if not action_definition: raise HTTPException(status_code=404, detail=f"Action definition not found: {action_key}") if action_definition.get("status") != "enabled": raise HTTPException(status_code=403, detail=f"Action disabled for current tenant: {action_key}") if action_definition.get("admin_only") and account.get("role") != "super_admin": raise HTTPException(status_code=403, detail="Current action is only available to platform administrators") if action_definition.get("requires_platform") and not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for this action") handler_key = action_definition.get("handler_key") or action_key usage_category = ACTION_USAGE_KEYS.get(handler_key, "") if usage_category: _enforce_tenant_quota(account, project_id=project["id"], usage_category=usage_category) latest_user_message = _last_user_message_text(request.session_id, account["id"]) if request.session_id else "" requested_payload = request.payload or {} def _recommended_action( action: str, *, label: str, summary: str, screen: str = "", **extra: Any, ) -> dict[str, Any]: payload = { "action": action, "label": label, "summary": summary, "screen": screen, } for key, value in extra.items(): if value is None: continue text = str(value).strip() if isinstance(value, str) else value if text == "": continue payload[key] = value return payload async def _run_platform_self_check() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for self-check") payload = _platform_self_check( account, platform=normalized_platform, project_id=project["id"], sample_limit=int((request.payload or {}).get("sample_limit") or 3), remember_summary=True, ) return { "title": f"{payload['platform_label']} Agent 自检", "summary": f"平台自检得分 {payload['score']},当前状态:{payload['readiness_label']}。", "payload": payload, "recommended_action": _recommended_action( "open-platform-agent-detail", label="查看平台 Agent", summary=f"继续查看 {payload['platform_label']} Agent 当前状态、自检建议和最近执行。", screen="playbook", platform=normalized_platform, ), } async def _run_storage_status() -> dict[str, Any]: payload = legacy.storage_status(project_id=project["id"], account=account) tenant_usage = payload.get("tenant_usage", {}) return { "title": "当前存储状态", "summary": ( f"项目 jobs 占用 {tenant_usage.get('project_jobs', {}).get('human_size', '0B')}," f"downloads 占用 {tenant_usage.get('project_downloads', {}).get('human_size', '0B')}。" ), "payload": payload, "recommended_action": _recommended_action( "goto-automation", label="去自动流程", summary="继续查看存储、依赖和自动流程健康状态。", screen="automation", ), } async def _run_live_recorder_status() -> dict[str, Any]: payload = legacy.live_recorder_status(project_id=project["id"], account=account) return { "title": "直播录制状态", "summary": f"当前共 {len(payload.get('items', []))} 条录制源,最近文件 {len(payload.get('files', []))} 个。", "payload": payload, "recommended_action": _recommended_action( "open-live-recorder", label="打开录制维护", summary="继续查看录制源、文件和 NAS 录制状态。", screen="production", ), } async def _run_ops_scan() -> dict[str, Any]: admin = legacy.require_super_admin(account) payload = _scan_admin_incidents(admin) return { "title": "运维 Agent 故障扫描", "summary": f"本轮共归集 {payload.get('count', 0)} 条事件。", "payload": payload, "recommended_action": _recommended_action( "goto-automation", label="去自动流程", summary="继续检查运维扫描结果、依赖健康和自动流程状态。", screen="automation", ), } async def _run_generate_copy() -> dict[str, Any]: assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=normalized_platform) if not assistant: raise HTTPException(status_code=404, detail="No execution assistant available") brief = str((request.payload or {}).get("brief") or latest_user_message or "").strip() if not brief: brief = f"请基于当前项目目标,输出一版适合{legacy.platform_label(normalized_platform or 'douyin')}发布的短视频文案。" payload = await legacy.generate_copy( assistant["id"], legacy.GenerateCopyRequest( brief=brief, platform=normalized_platform or "douyin", audience=str((request.payload or {}).get("audience") or "创业者"), extra_requirements=str((request.payload or {}).get("extra_requirements") or ""), knowledge_base_ids=list((request.payload or {}).get("knowledge_base_ids") or []), ), account, ) return { "title": "OneLiner 已生成文案", "summary": f"已用 {assistant.get('name') or '默认 Agent'} 生成一版可发布文案。", "payload": payload, "recommended_action": _recommended_action( "open-generate-copy", label="继续调文案", summary="继续修改提示、受众和补充要求,快速迭代这版文案。", screen="playbook", platform=normalized_platform or "douyin", ), } async def _run_review_draft() -> dict[str, Any]: latest_job = _latest_project_job(account, project_id=project["id"]) if not latest_job: raise HTTPException(status_code=404, detail="No completed job available for review draft") existing = legacy.db.fetch_one( "SELECT * FROM publish_reviews WHERE user_id = ? AND source_job_id = ? ORDER BY created_at DESC LIMIT 1", (account["id"], latest_job["id"]), ) if existing: payload = legacy.review_payload(existing) return { "title": "OneLiner 找到已有复盘", "summary": f"任务「{latest_job.get('title') or latest_job['id']}」已经有复盘记录。", "payload": payload, "recommended_action": _recommended_action( "open-review-edit", label="打开复盘", summary="继续完善这条复盘记录的 verdict、亮点和下一步。", screen="review", review_id=payload.get("id", ""), job_id=payload.get("source_job_id", ""), ), } assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=normalized_platform) result = latest_job.get("result_json") or "{}" try: result_map = json.loads(result) except json.JSONDecodeError: result_map = {} payload = legacy.create_review( legacy.ReviewCreateRequest( project_id=project["id"], source_job_id=latest_job["id"], assistant_id=(assistant or {}).get("id", ""), title=f"{latest_job.get('title') or '任务'} 复盘草稿", platform=normalized_platform or "douyin", content_type="video", verdict="待补充", highlights=str(result_map.get("summary") or result_map.get("headline_summary") or "")[:400], next_actions="补充发布结果、完善指标、确认下一步动作。", notes=str((request.payload or {}).get("notes") or "由 OneLiner 自动生成复盘草稿。"), ), account, ) return { "title": "OneLiner 已生成复盘草稿", "summary": f"已基于最近完成任务「{latest_job.get('title') or latest_job['id']}」生成复盘草稿。", "payload": payload, "recommended_action": _recommended_action( "open-review-edit", label="打开复盘", summary="继续完善这条复盘草稿,并确认 verdict 和下一步动作。", screen="review", review_id=payload.get("id", ""), job_id=payload.get("source_job_id", ""), ), } async def _run_import_homepage() -> dict[str, Any]: source_url = str( requested_payload.get("source_url") or requested_payload.get("sourceUrl") or _extract_first_url(latest_user_message) or "" ).strip() if not source_url: raise HTTPException(status_code=400, detail="No homepage URL available for import") inferred_platform = normalize_platform_from_text( requested_payload.get("platform") or requested_payload.get("platform_label") or normalized_platform or legacy.infer_platform_from_url(source_url) ) or _safe_platform(legacy.infer_platform_from_url(source_url), fallback="douyin") assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=inferred_platform) existing_source = _find_creator_source_by_url( account, project_id=project["id"], platform=inferred_platform, source_url=source_url, ) sync_job = await legacy.create_content_source_sync_job( legacy.ContentSourceSyncRequest( project_id=project["id"], knowledge_base_id=str(requested_payload.get("knowledge_base_id") or requested_payload.get("knowledgeBaseId") or ""), assistant_id=(assistant or {}).get("id", ""), content_source_id=(existing_source or {}).get("id", ""), platform=inferred_platform, handle=str(requested_payload.get("handle") or ""), source_url=source_url, title=str(requested_payload.get("title") or requested_payload.get("name") or ""), analysis_model_profile_id=str(requested_payload.get("analysis_model_profile_id") or requested_payload.get("analysisModelProfileId") or ""), language=str(requested_payload.get("language") or "auto"), max_items=max(1, min(int(requested_payload.get("max_items") or requested_payload.get("maxItems") or 5), 20)), skip_existing=bool(requested_payload.get("skip_existing", requested_payload.get("skipExisting", True))), auto_trigger_analysis=bool(requested_payload.get("auto_trigger_analysis", requested_payload.get("autoTriggerAnalysis", True))), ), account, ) return { "title": "OneLiner 已导入主页", "summary": f"已把主页接入当前项目,并触发 {legacy.platform_label(inferred_platform)} 内容源同步。", "payload": { "job": sync_job, "platform": inferred_platform, "source_url": source_url, "existing_source_id": (existing_source or {}).get("id", ""), }, "recommended_action": _recommended_action( "open-job-detail", label="看任务详情", summary=f"继续查看 {legacy.platform_label(inferred_platform)} 主页导入任务的同步进度和后续分析结果。", screen="production", platform=inferred_platform, job_id=sync_job.get("id", ""), ), } async def _run_analyze_account() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for account analysis") target_account = _resolve_platform_target_account( account, project_id=project["id"], platform=normalized_platform, requested_account_id=str(requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or ""), ) if not target_account: raise HTTPException(status_code=404, detail="No platform account available for analysis") body = { "model_profile_ids": list(requested_payload.get("model_profile_ids") or requested_payload.get("modelProfileIds") or []), "linked_account_ids": list(requested_payload.get("linked_account_ids") or requested_payload.get("linkedAccountIds") or []), "include_linked_accounts": bool(requested_payload.get("include_linked_accounts", requested_payload.get("includeLinkedAccounts", True))), "include_recent_similar_candidates": bool(requested_payload.get("include_recent_similar_candidates", requested_payload.get("includeRecentSimilarCandidates", True))), "max_videos": max(1, min(int(requested_payload.get("max_videos") or requested_payload.get("maxVideos") or 6), 20)), "extra_focus": str(requested_payload.get("extra_focus") or requested_payload.get("extraFocus") or latest_user_message or ""), "temperature": float(requested_payload.get("temperature") or 0.35), } if normalized_platform == "douyin": body["auto_analyze_top_videos"] = bool(requested_payload.get("auto_analyze_top_videos", requested_payload.get("autoAnalyzeTopVideos", True))) body["top_video_analysis_count"] = max(1, min(int(requested_payload.get("top_video_analysis_count") or requested_payload.get("topVideoAnalysisCount") or 6), 10)) else: body["auto_analyze_top_videos"] = bool(requested_payload.get("auto_analyze_top_videos", requested_payload.get("autoAnalyzeTopVideos", False))) body["top_video_analysis_count"] = max(1, min(int(requested_payload.get("top_video_analysis_count") or requested_payload.get("topVideoAnalysisCount") or 4), 10)) payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/accounts/{target_account['id']}/analysis", json_body=body, ) return { "title": "OneLiner 已分析账号", "summary": f"已为 {legacy.platform_label(normalized_platform)} 账号生成分析结论和下一步建议。", "payload": { "platform": normalized_platform, "account_id": target_account["id"], "analysis": payload, }, "recommended_action": _recommended_action( "select-account", label="打开当前对象", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 账号分析报告、快照和拆解结果。", screen="discovery", account_id=target_account["id"], ), } async def _run_track_account() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for tracking") target_account = _resolve_platform_target_account( account, project_id=project["id"], platform=normalized_platform, requested_account_id=str(requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or ""), ) if not target_account: raise HTTPException(status_code=404, detail="No platform account available for tracking") assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=normalized_platform) tracked_payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/tracking/accounts", json_body={ "tracked_account_id": target_account["id"], "assistant_id": (assistant or {}).get("id", ""), "note": str(requested_payload.get("note") or "由 OneLiner 直接加入跟踪。"), }, ) refreshed_payload = None if bool(requested_payload.get("refresh_now", True)): refreshed_payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/tracking/accounts/{target_account['id']}/refresh", json_body={}, ) sync_job_id = str((refreshed_payload or {}).get("sync_job_id") or "").strip() recommended_action = ( _recommended_action( "open-job-detail", label="看任务详情", summary="继续查看这条跟踪同步任务的执行进度。", screen="production", job_id=sync_job_id, ) if sync_job_id else _recommended_action( "refresh-tracked-account", label="继续同步当前账号", summary="继续查看当前已跟踪账号的最新同步和日报。", screen="tracking", tracked_account_id=target_account["id"], ) ) return { "title": "OneLiner 已加入跟踪", "summary": f"已把当前 {legacy.platform_label(normalized_platform)} 账号加入跟踪,并触发一次同步。", "payload": { "platform": normalized_platform, "account_id": target_account["id"], "tracking": tracked_payload, "refresh": refreshed_payload or {}, }, "recommended_action": recommended_action, } async def _run_refresh_tracking() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for tracking refresh") payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/tracking/refresh", json_body={}, ) items = list(payload.get("items") or []) sync_job_id = str((items[0] or {}).get("sync_job_id") or "").strip() if len(items) == 1 else "" recommended_action = ( _recommended_action( "open-job-detail", label="看同步任务", summary="继续查看这批跟踪同步任务里最新的一条执行进度。", screen="production", job_id=sync_job_id, ) if sync_job_id else _recommended_action( "goto-tracking", label="回到跟踪工作区", summary="继续查看当前平台跟踪池的同步结果和日报变化。", screen="tracking", platform=normalized_platform, ) ) return { "title": "OneLiner 已同步跟踪池", "summary": f"已为 {legacy.platform_label(normalized_platform)} 跟踪池触发同步,成功 {int(payload.get('refreshed') or 0)} 条。", "payload": { "platform": normalized_platform, "refresh": payload, }, "recommended_action": recommended_action, } async def _run_mark_tracking_read() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for tracking cursor update") last_seen_at = str( requested_payload.get("last_seen_at") or requested_payload.get("lastSeenAt") or legacy.utc_now() ).strip() or legacy.utc_now() payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/tracking/cursor", json_body={"last_seen_at": last_seen_at}, ) return { "title": "OneLiner 已标记日报已读", "summary": f"已把 {legacy.platform_label(normalized_platform)} 跟踪日报更新为已读,后续将从新的时间点继续汇总。", "payload": { "platform": normalized_platform, "cursor": payload, }, "recommended_action": _recommended_action( "goto-tracking", label="回到跟踪工作区", summary="继续查看当前平台跟踪日报和下一步跟进动作。", screen="tracking", platform=normalized_platform, ), } async def _run_search_similar_accounts() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for similarity search") source_account = _resolve_platform_target_account( account, project_id=project["id"], platform=normalized_platform, requested_account_id=str( requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or requested_payload.get("source_account_id") or requested_payload.get("sourceAccountId") or "" ), ) if not source_account: raise HTTPException(status_code=404, detail="No platform account available for similarity search") search_payload = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/similar-searches", json_body={ "source_account_id": source_account["id"], "candidate_urls": list(requested_payload.get("candidate_urls") or requested_payload.get("candidateUrls") or []), "seed_linked_accounts": bool(requested_payload.get("seed_linked_accounts", requested_payload.get("seedLinkedAccounts", True))), "search_public_pages": bool(requested_payload.get("search_public_pages", requested_payload.get("searchPublicPages", True))), "model_profile_id": str(requested_payload.get("model_profile_id") or requested_payload.get("modelProfileId") or ""), "max_candidates": max(1, min(int(requested_payload.get("max_candidates") or requested_payload.get("maxCandidates") or 8), 20)), "extra_requirements": str(requested_payload.get("extra_requirements") or requested_payload.get("extraRequirements") or latest_user_message or ""), }, ) search_id = str(search_payload.get("search_id") or search_payload.get("id") or "").strip() detail = await _call_local_api( account, method="GET", path=f"/v2/{normalized_platform}/similar-searches/{search_id}", ) if search_id else {"candidates": []} candidates = list(detail.get("candidates") or []) top_candidate = candidates[0] if candidates else {} top_candidate_account_id = str(top_candidate.get("candidate_account_id") or "").strip() recommended_action = ( _recommended_action( "select-account", label="打开当前候选", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 相似候选的详情、拆解和对标关系。", screen="discovery", account_id=top_candidate_account_id, search_id=search_id, ) if top_candidate_account_id else _recommended_action( "goto-discovery", label="回到找对标", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 相似候选列表和高分样本。", screen="discovery", search_id=search_id, ) ) return { "title": "OneLiner 已查到相似账号", "summary": f"已为 {legacy.platform_label(normalized_platform)} 当前账号生成 {len(candidates)} 个相似候选。", "payload": { "platform": normalized_platform, "source_account_id": source_account["id"], "search": { "id": search_id, "candidate_count": len(candidates), "top_candidate_account_id": top_candidate_account_id, }, "detail": detail, }, "recommended_action": recommended_action, } async def _run_save_benchmark_link() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for benchmark linking") source_account = _resolve_platform_target_account( account, project_id=project["id"], platform=normalized_platform, requested_account_id=str( requested_payload.get("source_account_id") or requested_payload.get("sourceAccountId") or requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or "" ), ) if not source_account: raise HTTPException(status_code=404, detail="No platform account available for benchmark linking") latest_similarity = _latest_similarity_candidate( account, platform=normalized_platform, source_account_id=source_account["id"], ) or {} candidate_payload = latest_similarity.get("candidate") or {} target_account_id = str( requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or candidate_payload.get("candidate_account_id") or "" ).strip() target_profile_url = str( requested_payload.get("target_profile_url") or requested_payload.get("targetProfileUrl") or ("" if target_account_id else candidate_payload.get("candidate_profile_url")) or "" ).strip() if not target_account_id and not target_profile_url: raise HTTPException(status_code=404, detail="No benchmark candidate available to save") created = await _call_local_api( account, method="POST", path=f"/v2/{normalized_platform}/accounts/{source_account['id']}/benchmark-links", json_body={ "target_account_ids": [target_account_id] if target_account_id else [], "target_profile_urls": [] if target_account_id else [target_profile_url], "relation_type": str(requested_payload.get("relation_type") or requested_payload.get("relationType") or "benchmark"), "note": str(requested_payload.get("note") or candidate_payload.get("rationale_text") or "由 OneLiner 直接加入对标库。"), "search_id": str(requested_payload.get("search_id") or requested_payload.get("searchId") or latest_similarity.get("search_id") or ""), }, ) links = list(created.get("links") or []) latest_link = links[0] if links else {} recommended_action = ( _recommended_action( "select-account", label="打开当前对标", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 当前对标账号的详情、关系和高分样本。", screen="discovery", account_id=target_account_id, ) if target_account_id else _recommended_action( "goto-discovery", label="回到找对标", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 对标关系和相似候选。", screen="discovery", ) ) return { "title": "OneLiner 已存对标关系", "summary": f"已把当前候选加入 {legacy.platform_label(normalized_platform)} 对标关系。", "payload": { "platform": normalized_platform, "source_account_id": source_account["id"], "target_account_id": target_account_id, "target_profile_url": target_profile_url, "search_id": str(latest_similarity.get("search_id") or ""), "link": latest_link, "links": links, }, "recommended_action": recommended_action, } async def _run_analyze_top_videos() -> dict[str, Any]: if not normalized_platform: raise HTTPException(status_code=400, detail="Platform is required for top video analysis") target_account = None requested_account_id = str(requested_payload.get("target_account_id") or requested_payload.get("targetAccountId") or "").strip() if requested_account_id and normalized_platform != "douyin": target_account = legacy.db.fetch_one( """ SELECT * FROM content_sources WHERE id = ? AND user_id = ? AND project_id = ? AND platform = ? AND source_kind = 'creator_account' """, (requested_account_id, account["id"], project["id"], normalized_platform), ) if not target_account: target_account = _latest_platform_account(account, project_id=project["id"], platform=normalized_platform) videos = _linked_platform_videos( account, project_id=project["id"], platform=normalized_platform, account_row=target_account or {}, limit=max(2, min(int(requested_payload.get("top_video_count") or requested_payload.get("topVideoCount") or 6), 12)), ) if target_account else [] account_payload = legacy.content_source_payload(target_account) if target_account else None if not videos: account_payload, videos = _fallback_platform_videos( account, project_id=project["id"], platform=normalized_platform, requested_account_id=requested_account_id, limit=max(2, min(int(requested_payload.get("top_video_count") or requested_payload.get("topVideoCount") or 6), 12)), ) if not account_payload: raise HTTPException(status_code=404, detail="No platform account available for top video analysis") min_score = float(requested_payload.get("min_score") or requested_payload.get("minScore") or 0) ranked = [item for item in videos if float((item.get("score") or {}).get("performance_score") or 0) >= min_score] if not ranked: raise HTTPException(status_code=404, detail="No candidate videos available for analysis") profile = legacy.model_profile_for_account( account["id"], str(requested_payload.get("model_profile_id") or requested_payload.get("modelProfileId") or ""), ) items: list[dict[str, Any]] = [] parse_json_object = getattr(legacy, "parse_json_object", None) for video in ranked: prompt = ( f"请拆解这条{legacy.platform_label(normalized_platform)}作品为什么值得关注," "输出 JSON,字段包括 summary、borrow_points、risks、next_actions。" f"\n\n输入:\n{json.dumps(video, ensure_ascii=False, indent=2)}" ) output = await legacy.call_model( profile, "你是平台内容拆解助手。尽量输出 JSON,字段包括 summary、borrow_points、risks、next_actions。", prompt, temperature=float(requested_payload.get("temperature") or 0.25), ) parsed = parse_json_object(output) if callable(parse_json_object) else _parse_json(output, {}) summary_text = str(parsed.get("summary") or parsed.get("headline_summary") or output).strip()[:240] items.append( { "id": make_id(f"{normalized_platform}_va"), "video_id": video["id"], "video_title": video["title"], "status": "ok", "summary_text": summary_text, "parsed_json": parsed, "performance_score": (video.get("score") or {}).get("performance_score", 0), "latest_job_id": video.get("latest_job_id", ""), "created_at": now(), } ) memory = _remember_platform_observation( account, project_id=project["id"], platform=normalized_platform, memory_key=f"top_videos::{target_account['id']}", title=f"{legacy.platform_label(normalized_platform)} 高分作品拆解", summary=f"已拆解 {len(items)} 条高分作品,继续固化有效结构与风险判断。", details={ "account_id": account_payload["id"], "items": items, }, confidence=0.84, ) return { "title": "OneLiner 已分析高分作品", "summary": f"已为 {legacy.platform_label(normalized_platform)} 账号拆解 {len(items)} 条高分作品。", "payload": { "platform": normalized_platform, "account": account_payload, "analyzed_count": len(items), "items": items, "memory": memory, }, "recommended_action": _recommended_action( "select-account", label="打开当前对象", summary=f"继续查看 {legacy.platform_label(normalized_platform)} 当前对象的高分作品拆解和相似账号。", screen="discovery", account_id=account_payload.get("id", ""), platform=normalized_platform, ), } async def _run_create_ai_video() -> dict[str, Any]: source_job = _load_owned_job(account, str(requested_payload.get("source_job_id") or requested_payload.get("sourceJobId") or "")) or _latest_derivable_job( account, project_id=project["id"], exclude_line_types={"ai_video"}, ) if not source_job: raise HTTPException(status_code=404, detail="No completed source job available for AI video") assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=normalized_platform) brief = str( requested_payload.get("brief") or requested_payload.get("video_brief") or requested_payload.get("videoBrief") or latest_user_message or _assistant_brief_from_job(source_job) or "" ).strip() if not brief: brief = f"请基于任务「{source_job.get('title') or source_job['id']}」输出一版适合短视频平台的 AI 视频。" source_artifacts = legacy.parse_job_artifacts(source_job) video_provider = str( requested_payload.get("video_provider") or requested_payload.get("videoProvider") or source_artifacts.get("video_provider") or "doubao" ).strip() or "doubao" video_model = str( requested_payload.get("video_model") or requested_payload.get("videoModel") or source_artifacts.get("video_model") or "" ).strip() if video_provider == "seedance2" and not video_model: video_model = "seedance-2.0-pro" job = await legacy.create_ai_video_job( legacy.AiVideoJobRequest( project_id=project["id"], assistant_id=(assistant or {}).get("id", ""), knowledge_base_id=str(requested_payload.get("knowledge_base_id") or requested_payload.get("knowledgeBaseId") or source_job.get("knowledge_base_id") or ""), source_job_id=source_job["id"], title=str(requested_payload.get("title") or f"{source_job.get('title') or '任务'} · AI 视频"), brief=brief, style=str(requested_payload.get("style") or "realistic"), shots=max(1, min(int(requested_payload.get("shots") or 4), 12)), duration=max(3, min(int(requested_payload.get("duration") or 5), 12)), video_provider=video_provider, video_model=video_model, ), account, ) return { "title": "OneLiner 已创建 AI 视频任务", "summary": f"已基于「{source_job.get('title') or source_job['id']}」创建 AI 视频任务,当前引擎 {('Seedance 2.0' if video_provider == 'seedance2' else '默认视频引擎')}。", "payload": { "job": job, "source_job": legacy.job_payload(source_job), "brief": brief, "video_provider": video_provider, "video_model": video_model, }, "recommended_action": _recommended_action( "open-job-detail", label="看任务详情", summary="继续查看这条 AI 视频任务的执行进度和后续动作。", screen="production", job_id=job.get("id", ""), ), } async def _run_create_assistant() -> dict[str, Any]: default_name = str( requested_payload.get("name") or requested_payload.get("assistant_name") or requested_payload.get("assistantName") or (f"{legacy.platform_label(normalized_platform)} 执行 Agent" if normalized_platform else f"{project.get('name') or '项目'} Agent") ).strip() assistant = legacy.create_assistant( legacy.AssistantCreateRequest( project_id=project["id"], name=default_name, description=str(requested_payload.get("description") or f"由 OneLiner 基于当前项目上下文创建,用于承接{legacy.platform_label(normalized_platform) if normalized_platform else '当前项目'}任务。"), generation_goal=str(requested_payload.get("generation_goal") or requested_payload.get("goal") or f"承接{legacy.platform_label(normalized_platform) if normalized_platform else '当前项目'}内容生产和分析动作。"), system_prompt=str(requested_payload.get("system_prompt") or requested_payload.get("systemPrompt") or ""), knowledge_base_ids=list(requested_payload.get("knowledge_base_ids") or requested_payload.get("knowledgeBaseIds") or []), model_profile_id=str(requested_payload.get("model_profile_id") or requested_payload.get("modelProfileId") or ""), ), account, ) return { "title": "OneLiner 已创建 Agent", "summary": f"已在当前项目下创建 Agent「{assistant.get('name') or '新 Agent'}」。", "payload": {"assistant": assistant}, "recommended_action": _recommended_action( "open-edit-assistant", label="继续编辑 Agent", summary="继续补齐这条 Agent 的说明、目标和知识绑定。", screen="playbook", assistant_id=assistant.get("id", ""), ), } async def _run_create_real_cut() -> dict[str, Any]: source_job = _load_owned_job(account, str(requested_payload.get("source_job_id") or requested_payload.get("sourceJobId") or "")) or _latest_derivable_job( account, project_id=project["id"], exclude_line_types={"ai_video", "real_cut"}, ) if not source_job: raise HTTPException(status_code=404, detail="No completed source job available for real cut") job = await legacy.create_real_cut_job( legacy.RealCutJobRequest( project_id=project["id"], title=str(requested_payload.get("title") or f"{source_job.get('title') or '任务'} · 实拍剪辑"), source_job_id=source_job["id"], objective=str( requested_payload.get("objective") or "保留高信息密度片段,输出适合短视频平台的粗剪结果" ), target_duration_sec=max(10, min(int(requested_payload.get("target_duration_sec") or requested_payload.get("targetDurationSec") or 60), 300)), target_aspect_ratio=str(requested_payload.get("target_aspect_ratio") or requested_payload.get("targetAspectRatio") or "9:16"), review_enabled=bool(requested_payload.get("review_enabled", requested_payload.get("reviewEnabled", False))), ), account, ) return { "title": "OneLiner 已创建实拍剪辑任务", "summary": f"已基于「{source_job.get('title') or source_job['id']}」创建实拍剪辑任务。", "payload": { "job": job, "source_job": legacy.job_payload(source_job), }, "recommended_action": _recommended_action( "open-job-detail", label="看任务详情", summary="继续查看这条实拍剪辑任务的执行进度和恢复动作。", screen="production", job_id=job.get("id", ""), ), } async def _run_save_live_recorder_source() -> dict[str, Any]: source_url = str( requested_payload.get("source_url") or requested_payload.get("sourceUrl") or _extract_first_url(latest_user_message) or "" ).strip() if not source_url: raise HTTPException(status_code=400, detail="No live recorder source URL available") recorder_platform = normalize_platform_from_text( requested_payload.get("platform") or requested_payload.get("platform_label") or normalized_platform or legacy.infer_platform_from_url(source_url) ) or _safe_platform(legacy.infer_platform_from_url(source_url), fallback="kuaishou") assistant = _resolve_execution_assistant(account, project_id=project["id"], platform=recorder_platform) saved = legacy.create_live_recorder_source( legacy.LiveRecorderSourceCreateRequest( project_id=project["id"], assistant_id=(assistant or {}).get("id", ""), platform=recorder_platform, source_url=source_url, title=str(requested_payload.get("title") or ""), quality=str(requested_payload.get("quality") or "原画"), enabled=bool(requested_payload.get("enabled", True)), ), account, ) started = None if bool(requested_payload.get("auto_start", requested_payload.get("autoStart", True))): try: started = legacy.live_recorder_start(account) except Exception as exc: started = {"ok": False, "message": str(exc)} return { "title": "OneLiner 已保存录制源", "summary": f"已把直播源保存到当前租户的 NAS 录制配置里。", "payload": { "saved": saved, "started": started, "platform": recorder_platform, "source_url": source_url, }, "recommended_action": _recommended_action( "edit-live-recorder-source", label="继续录制维护", summary="继续查看这条录制源的启停状态、项目归属和录制文件。", screen="production", source_id=(saved or {}).get("id", ""), ), } executors = { "platform-self-check": _run_platform_self_check, "storage-status": _run_storage_status, "live-recorder-status": _run_live_recorder_status, "scan-admin-ops": _run_ops_scan, "generate-copy": _run_generate_copy, "review-draft": _run_review_draft, "import-homepage": _run_import_homepage, "analyze-account": _run_analyze_account, "track-account": _run_track_account, "refresh-tracking": _run_refresh_tracking, "mark-tracking-read": _run_mark_tracking_read, "search-similar-accounts": _run_search_similar_accounts, "save-benchmark-link": _run_save_benchmark_link, "analyze-top-videos": _run_analyze_top_videos, "create-assistant": _run_create_assistant, "create-ai-video": _run_create_ai_video, "create-real-cut": _run_create_real_cut, "save-live-recorder-source": _run_save_live_recorder_source, } executor = executors.get(handler_key) if not executor: raise HTTPException(status_code=400, detail=f"Unsupported OneLiner action: {handler_key}") result = await executor() usage_entry = None if usage_category: payload_map = result.get("payload") or {} job_map = payload_map.get("job") or {} saved_map = (payload_map.get("saved") or {}).get("item") or {} usage_entry = _record_tenant_usage( account, project_id=project["id"], category=usage_category, reference_type=( "job" if job_map.get("id") else "live_recorder_source" if saved_map.get("binding_id") else "action" ), reference_id=job_map.get("id") or saved_map.get("binding_id") or handler_key, details={ "action_key": action_key, "handler_key": handler_key, "platform": normalized_platform, }, ) if request.session_id: session = _load_owned_session(request.session_id, account) _insert_message( session["id"], account["id"], "assistant", result["summary"], { "intent_key": "custom", "delivery_mode": "oneliner", "platform": normalized_platform, "suggested_actions": [], }, { "summary_text": result["summary"], "execution_result": result, }, ) return { "action_key": action_key, "handler_key": handler_key, "project_id": project["id"], "platform": normalized_platform, "executed_at": now(), "action_definition": action_definition, "usage_entry": usage_entry, **result, } @app.post("/v2/oneliner/runs") def create_oneliner_run( request: AgentRunCreateRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = _safe_platform(request.platform, fallback="") if str(request.platform or "").strip() else "" platform_scope = _normalize_platform_scope(request.platform_scope) governance = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform=normalized_platform, ) profile_row = _fetch_profile_row(account, project["id"]) or _ensure_oneliner_profile(account, project["id"]) platform_profile_row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], normalized_platform), ) if normalized_platform else None oneliner_profile_bundle = _oneliner_profile_runtime_snapshot(profile_row, account=account) governance_snapshot = { **governance, "oneliner_profile": oneliner_profile_bundle, "oneliner_profile_version": oneliner_profile_bundle.get("current_version") or {}, "platform_agent_profile": _platform_agent_runtime_snapshot( account, platform_profile_row, platform=normalized_platform, project_id=project["id"], ) if normalized_platform else {}, } plan = _agent_run_plan_payload( request, governance=governance_snapshot, platform=normalized_platform, platform_scope=platform_scope, ) session = _ensure_run_session( account, project_id=project["id"], requested_session_id=request.session_id, title=request.title.strip() or plan["goal"], preferred_platform=normalized_platform or "douyin", ) _touch_session_for_run(session["id"], platform=normalized_platform, intent_key=plan.get("intent_key", "custom")) run_id = make_id("oline_run") timestamp = now() active_admin_override_notice = governance_snapshot.get("active_admin_override_notice") or {} legacy.db.execute( """ INSERT INTO agent_runs ( id, user_id, project_id, session_id, source_screen, source_action_key, title, summary, intent_key, platform, platform_scope, delivery_mode, run_status, scheduling_mode, active_executor_key, plan_json, governance_json, result_json, status_summary, needs_user_input, blocked_reason, active_admin_override_notice_json, created_at, updated_at, started_at, finished_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'needs_confirmation', ?, 'main_agent', ?, ?, '{}', ?, 1, '', ?, ?, ?, '', '') """, ( run_id, account["id"], project["id"], session["id"], str(request.source_screen or "").strip(), str(request.source_action_key or "").strip(), request.title.strip() or plan["goal"], request.summary.strip(), str(request.intent_key or "custom").strip() or "custom", normalized_platform, platform_scope, _normalize_delivery_mode(request.delivery_mode), _normalize_scheduling_mode(request.scheduling_mode), _dump(plan), _dump(governance_snapshot), "等待你确认执行计划", _dump(active_admin_override_notice), timestamp, timestamp, ), ) _log_agent_run_event( run_id, event_type="run.created", summary=f"已创建待确认任务:{request.title.strip() or plan['goal']}", details={ "run_status": "needs_confirmation", "source_screen": str(request.source_screen or "").strip(), "source_action_key": str(request.source_action_key or "").strip(), "platform": normalized_platform, "platform_scope": platform_scope, }, ) row = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (run_id,)) assert row is not None return _agent_run_payload(row) @app.post("/v2/oneliner/runs/{run_id}/retry") def retry_oneliner_run( run_id: str, request: AgentRunRetryRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: row = _load_owned_agent_run(run_id, account) current_status = str(row.get("run_status") or "") if current_status not in {"cancelled", "blocked", "failed", "done"}: raise HTTPException(status_code=409, detail="Run can not be retried yet") project_id = str(row.get("project_id") or "").strip() platform = str(row.get("platform") or "").strip() platform_scope = _normalize_platform_scope(str(row.get("platform_scope") or "single_platform")) governance = _effective_policy_payload( subject_account=account, subject_project_id=project_id, platform=platform, ) profile_row = _fetch_profile_row(account, project_id) or _ensure_oneliner_profile(account, project_id) platform_profile_row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project_id, platform), ) if platform else None oneliner_profile_bundle = _oneliner_profile_runtime_snapshot(profile_row, account=account) governance_snapshot = { **governance, "oneliner_profile": oneliner_profile_bundle, "oneliner_profile_version": oneliner_profile_bundle.get("current_version") or {}, "platform_agent_profile": _platform_agent_runtime_snapshot( account, platform_profile_row, platform=platform, project_id=project_id, ) if platform else {}, } plan = _parse_json(row.get("plan_json"), {}) session_id = str(row.get("session_id") or "").strip() _touch_session_for_run(session_id, platform=platform, intent_key=str(row.get("intent_key") or "custom").strip() or "custom") next_run_id = make_id("oline_run") timestamp = now() active_admin_override_notice = governance_snapshot.get("active_admin_override_notice") or {} legacy.db.execute( """ INSERT INTO agent_runs ( id, user_id, project_id, session_id, source_screen, source_action_key, title, summary, intent_key, platform, platform_scope, delivery_mode, run_status, scheduling_mode, active_executor_key, plan_json, governance_json, result_json, status_summary, needs_user_input, blocked_reason, active_admin_override_notice_json, created_at, updated_at, started_at, finished_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'needs_confirmation', ?, 'main_agent', ?, ?, '{}', ?, 1, '', ?, ?, ?, '', '') """, ( next_run_id, account["id"], project_id, session_id, str(row.get("source_screen") or "").strip(), str(row.get("source_action_key") or "").strip(), str(row.get("title") or plan.get("goal") or "主 Agent 任务").strip() or "主 Agent 任务", str(request.reason or row.get("summary") or "").strip() or str(row.get("summary") or "").strip(), str(row.get("intent_key") or "custom").strip() or "custom", platform, platform_scope, _normalize_delivery_mode(str(row.get("delivery_mode") or "hybrid")), _normalize_scheduling_mode(str(row.get("scheduling_mode") or "queued")), _dump(plan), _dump(governance_snapshot), "等待你确认执行计划", _dump(active_admin_override_notice), timestamp, timestamp, ), ) _log_agent_run_event( next_run_id, event_type="run.created", summary=f"已创建待确认任务:{str(row.get('title') or plan.get('goal') or '主 Agent 任务').strip() or '主 Agent 任务'}", details={ "run_status": "needs_confirmation", "source_screen": str(row.get("source_screen") or "").strip(), "source_action_key": str(row.get("source_action_key") or "").strip(), "platform": platform, "platform_scope": platform_scope, }, ) _log_agent_run_event( next_run_id, event_type="run.retried", summary=str(request.reason or "已基于上一轮主 Agent 任务重新生成待确认执行卡").strip(), details={"retry_from_run_id": run_id, "from_status": current_status}, ) _log_agent_run_event( run_id, event_type="run.retried", summary=str(request.reason or "用户要求重新发起当前主 Agent 任务").strip(), details={"new_run_id": next_run_id, "from_status": current_status}, ) created = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (next_run_id,)) assert created is not None return _agent_run_payload(created) @app.get("/v2/oneliner/runs") def list_oneliner_runs( project_id: str | None = Query(default=None), limit: int = Query(default=20, ge=1, le=100), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) if (project_id or "").strip() else _resolve_project_for_read(account, None) if project: rows = legacy.db.fetch_all( """ SELECT * FROM agent_runs WHERE user_id = ? AND project_id = ? ORDER BY created_at DESC LIMIT ? """, (account["id"], project["id"], limit), ) else: rows = legacy.db.fetch_all( """ SELECT * FROM agent_runs WHERE user_id = ? ORDER BY created_at DESC LIMIT ? """, (account["id"], limit), ) items = [_agent_run_payload(row, include_events=False) for row in rows] return {"items": items, "count": len(items)} @app.get("/v2/oneliner/runs/{run_id}") def get_oneliner_run( run_id: str, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: row = _load_owned_agent_run(run_id, account) row = _complete_agent_run_for_read(row) return _agent_run_payload(row) @app.get("/v2/oneliner/runs/{run_id}/events") def list_oneliner_run_events( run_id: str, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: row = _load_owned_agent_run(run_id, account) row = _complete_agent_run_for_read(row) items = _list_agent_run_events(row["id"]) return {"run": _agent_run_payload(row, include_events=False), "items": items, "count": len(items)} @app.post("/v2/oneliner/runs/{run_id}/confirm") def confirm_oneliner_run( run_id: str, request: AgentRunConfirmRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: row = _load_owned_agent_run(run_id, account) current_status = str(row.get("run_status") or "needs_confirmation") if current_status not in {"needs_confirmation", "queued", "running"}: raise HTTPException(status_code=409, detail="Run can no longer be confirmed") if current_status == "needs_confirmation": _log_agent_run_event( run_id, event_type="run.confirmed", summary=request.reason.strip() or "用户已确认执行计划", details={"reason": request.reason.strip()}, ) next_status = "queued" if _has_other_active_runs(account_id=account["id"], project_id=row.get("project_id", ""), run_id=run_id) else "running" timestamp = now() started_at = row.get("started_at", "") event_type = "run.queued" event_summary = "已进入主 Agent 等待队列" status_summary = "等待主 Agent 执行" if next_status == "running": started_at = timestamp event_type = "run.started" event_summary = "主 Agent 已开始执行" status_summary = "主 Agent 正在执行" legacy.db.execute( """ UPDATE agent_runs SET run_status = ?, status_summary = ?, needs_user_input = 0, updated_at = ?, started_at = ? WHERE id = ? """, (next_status, status_summary, timestamp, started_at, run_id), ) _log_agent_run_event( run_id, event_type=event_type, summary=event_summary, details={"run_status": next_status}, ) updated = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (run_id,)) assert updated is not None return _agent_run_payload(updated) @app.post("/v2/oneliner/runs/{run_id}/cancel") def cancel_oneliner_run( run_id: str, request: AgentRunCancelRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: row = _load_owned_agent_run(run_id, account) current_status = str(row.get("run_status") or "") if current_status not in {"needs_confirmation", "queued"}: raise HTTPException(status_code=409, detail="Run can no longer be cancelled") timestamp = now() legacy.db.execute( """ UPDATE agent_runs SET run_status = 'cancelled', status_summary = ?, needs_user_input = 0, updated_at = ?, finished_at = ? WHERE id = ? """, (request.reason.strip() or "任务已取消", timestamp, timestamp, run_id), ) _log_agent_run_event( run_id, event_type="run.cancelled", summary=request.reason.strip() or "用户取消了当前任务", details={"from_status": current_status}, ) updated = legacy.db.fetch_one("SELECT * FROM agent_runs WHERE id = ?", (run_id,)) assert updated is not None return _agent_run_payload(updated) @app.get("/v2/oneliner/profile") def get_oneliner_profile( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) row = _ensure_oneliner_profile(account, project["id"]) return _oneliner_profile_bundle(row, account=account) @app.put("/v2/oneliner/profile") def put_oneliner_profile( request: OneLinerProfileRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) assistant = _resolve_assistant(account, request.assistant_id or None, project["id"]) existing = _ensure_oneliner_profile(account, project["id"]) timestamp = now() update_sql = """ UPDATE oneliner_profiles SET assistant_id = ?, display_name = ?, long_term_goal = ?, notes = ?, default_platform = ?, config_json = ?, updated_at = ? WHERE id = ? """ update_params = ( (assistant or {}).get("id", ""), request.display_name.strip() or "OneLiner", request.long_term_goal.strip(), request.notes.strip(), _safe_platform(request.default_platform or existing.get("default_platform") or "douyin"), _dump(request.config), timestamp, existing["id"], ) if (assistant or {}).get("id", ""): legacy.db.execute(update_sql, update_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(update_sql, update_params) conn.execute("PRAGMA foreign_keys=ON") row = legacy.db.fetch_one("SELECT * FROM oneliner_profiles WHERE id = ?", (existing["id"],)) assert row is not None version = _create_oneliner_profile_version( row, actor_user_id=account["id"], source_type="user_update", reason=request.reason.strip() or "更新 OneLiner 主配置", ) _log_oneliner_profile_audit( profile_id=row["id"], version_id=version["id"], actor_user_id=account["id"], action_key="update-oneliner-profile", summary=f"已更新 OneLiner「{row.get('display_name', 'OneLiner')}」主配置", details={"project_id": project["id"], "rollback_to_version_id": "", "assistant_id": row.get("assistant_id", "")}, ) return _oneliner_profile_bundle(row, account=account) @app.get("/v2/oneliner/profile/versions") def list_oneliner_profile_versions( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) row = _ensure_oneliner_profile(account, project["id"]) _ensure_oneliner_profile_version_seed(row, actor_user_id=account["id"]) items = _list_oneliner_profile_versions(row) return {"items": items, "count": len(items), "current_version": items[0] if items else None} @app.get("/v2/oneliner/profile/audits") def list_oneliner_profile_audits( project_id: str | None = Query(default=None), limit: int = Query(default=12, ge=1, le=50), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) row = _ensure_oneliner_profile(account, project["id"]) _ensure_oneliner_profile_version_seed(row, actor_user_id=account["id"]) items = _list_oneliner_profile_audits(row, limit=limit) return {"items": items, "count": len(items)} @app.post("/v2/oneliner/profile/rollback") def rollback_oneliner_profile( request: OneLinerProfileRollbackRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) row = _ensure_oneliner_profile(account, project["id"]) _ensure_oneliner_profile_version_seed(row, actor_user_id=account["id"]) target_version = legacy.db.fetch_one( """ SELECT * FROM oneliner_profile_versions WHERE id = ? AND profile_id = ? """, (request.version_id, row["id"]), ) if not target_version: raise HTTPException(status_code=404, detail="OneLiner profile version not found") assistant = _resolve_assistant(account, target_version.get("assistant_id", ""), project["id"]) timestamp = now() update_sql = """ UPDATE oneliner_profiles SET assistant_id = ?, display_name = ?, long_term_goal = ?, notes = ?, default_platform = ?, config_json = ?, updated_at = ? WHERE id = ? """ update_params = ( (assistant or {}).get("id", ""), target_version.get("display_name", "OneLiner"), target_version.get("long_term_goal", ""), target_version.get("notes", ""), _safe_platform(target_version.get("default_platform") or row.get("default_platform") or "douyin"), target_version.get("config_json", "{}"), timestamp, row["id"], ) if (assistant or {}).get("id", ""): legacy.db.execute(update_sql, update_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(update_sql, update_params) conn.execute("PRAGMA foreign_keys=ON") updated_row = legacy.db.fetch_one("SELECT * FROM oneliner_profiles WHERE id = ?", (row["id"],)) assert updated_row is not None version = _create_oneliner_profile_version( updated_row, actor_user_id=account["id"], source_type="user_rollback", reason=request.reason.strip() or f"回滚到版本 {target_version.get('version_no') or request.version_id}", rollback_from_version_id=target_version["id"], ) _log_oneliner_profile_audit( profile_id=updated_row["id"], version_id=version["id"], actor_user_id=account["id"], action_key="rollback-oneliner-profile", summary=f"已回滚 OneLiner 主配置到版本 {target_version.get('version_no') or request.version_id}", details={"project_id": project["id"], "rollback_to_version_id": target_version["id"]}, ) return _oneliner_profile_bundle(updated_row, account=account) @app.get("/v2/oneliner/sessions") def list_oneliner_sessions( project_id: str | None = Query(default=None), limit: int = Query(default=20, ge=1, le=100), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) rows = legacy.db.fetch_all( """ SELECT * FROM oneliner_sessions WHERE user_id = ? AND project_id = ? ORDER BY updated_at DESC LIMIT ? """, (account["id"], project["id"], limit), ) items = [_session_payload(row) for row in rows] return {"items": items, "count": len(items)} @app.post("/v2/oneliner/sessions") async def create_oneliner_session( request: OneLinerSessionCreateRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) profile = _ensure_oneliner_profile(account, project["id"]) session_id = make_id("oline") timestamp = now() preferred_platform = _safe_platform(request.preferred_platform or profile.get("default_platform") or "douyin") title = request.title.strip() or "新的 OneLiner 会话" legacy.db.execute( """ INSERT INTO oneliner_sessions ( id, user_id, project_id, profile_id, title, status, preferred_platform, last_platform, last_intent_key, last_message_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, 'active', ?, '', '', ?, ?, ?) """, ( session_id, account["id"], project["id"], profile["id"], title, preferred_platform, timestamp, timestamp, timestamp, ), ) session_row = legacy.db.fetch_one("SELECT * FROM oneliner_sessions WHERE id = ?", (session_id,)) if request.initial_message.strip(): await post_oneliner_message( session_id, OneLinerMessageRequest( content=request.initial_message, project_id=project["id"], platform=preferred_platform, ), account, ) session_row = legacy.db.fetch_one("SELECT * FROM oneliner_sessions WHERE id = ?", (session_id,)) return _session_payload(session_row) @app.get("/v2/oneliner/sessions/{session_id}/messages") def list_oneliner_messages( session_id: str, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: session = _load_owned_session(session_id, account) rows = legacy.db.fetch_all( "SELECT * FROM oneliner_messages WHERE session_id = ? ORDER BY created_at ASC", (session["id"],), ) items = [_message_payload(row) for row in rows] return {"session": _session_payload(session), "items": items, "count": len(items)} @app.post("/v2/oneliner/sessions/{session_id}/messages") async def post_oneliner_message( session_id: str, request: OneLinerMessageRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: session = _load_owned_session(session_id, account) project = _resolve_project(account, request.project_id or session.get("project_id") or None) plan = await _plan_oneliner_request( account, project_id=project["id"], message=request.content, platform_hint=request.platform or session.get("preferred_platform") or "", ) user_message = _insert_message(session["id"], account["id"], "user", request.content.strip(), {}, {}) remembered = _remember_message_preference(account, project_id=project["id"], plan=plan, message=request.content) result = await _generate_oneliner_reply(account, project_id=project["id"], message=request.content, plan=plan) if remembered: result["remembered_memory"] = remembered assistant_message = _insert_message(session["id"], account["id"], "assistant", result["summary_text"], plan, result) session_title = session.get("title") or request.content.strip()[:28] or "新的 OneLiner 会话" timestamp = now() legacy.db.execute( """ UPDATE oneliner_sessions SET title = ?, last_platform = ?, last_intent_key = ?, last_message_at = ?, updated_at = ? WHERE id = ? """, ( session_title, plan.get("platform", ""), plan.get("intent_key", ""), timestamp, timestamp, session["id"], ), ) updated_session = legacy.db.fetch_one("SELECT * FROM oneliner_sessions WHERE id = ?", (session["id"],)) return { "session": _session_payload(updated_session), "user_message": _message_payload(user_message), "assistant_message": _message_payload(assistant_message), "plan": plan, "result": result, } @app.post("/v2/oneliner/actions/execute") async def execute_oneliner_action( request: OneLinerActionExecuteRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: return await _execute_oneliner_action(account, request) @app.get("/v2/oneliner/action-registry") def list_oneliner_action_registry( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) items = _list_action_registry(account, project_id=project["id"]) return {"items": items, "count": len(items)} @app.put("/v2/oneliner/action-registry/{action_key}") def update_oneliner_action_registry( action_key: str, request: OneLinerActionDefinitionRequest, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) return _upsert_action_definition(account, project_id=project["id"], action_key=action_key, request=request) @app.get("/v2/platform-agents") def list_platform_agents( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) items = _list_platform_profiles(account, project["id"]) return {"items": items, "count": len(items)} @app.put("/v2/platform-agents/{platform}/profile") def update_platform_agent( platform: str, request: PlatformAgentProfileRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _upsert_platform_profile(account, normalized_platform, request) @app.get("/v2/platform-agents/{platform}/profile/versions") def list_platform_agent_profile_versions( platform: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], normalized_platform), ) if not row: return {"items": [], "count": 0, "current_version": None} _ensure_platform_agent_profile_version_seed(row, actor_user_id=account["id"]) items = _list_platform_agent_profile_versions(row) return {"items": items, "count": len(items), "current_version": items[0] if items else None} @app.get("/v2/platform-agents/{platform}/profile/audits") def list_platform_agent_profile_audits( platform: str, project_id: str | None = Query(default=None), limit: int = Query(default=12, ge=1, le=50), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], normalized_platform), ) if not row: return {"items": [], "count": 0} _ensure_platform_agent_profile_version_seed(row, actor_user_id=account["id"]) items = _list_platform_agent_profile_audits(row, limit=limit) return {"items": items, "count": len(items)} @app.post("/v2/platform-agents/{platform}/profile/rollback") def rollback_platform_agent_profile( platform: str, request: PlatformAgentProfileRollbackRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = _safe_platform(platform) row = legacy.db.fetch_one( "SELECT * FROM platform_agent_profiles WHERE user_id = ? AND project_id = ? AND platform = ?", (account["id"], project["id"], normalized_platform), ) if not row: raise HTTPException(status_code=404, detail="Platform agent profile not found") _ensure_platform_agent_profile_version_seed(row, actor_user_id=account["id"]) target_version = legacy.db.fetch_one( """ SELECT * FROM platform_agent_profile_versions WHERE id = ? AND profile_id = ? """, (request.version_id, row["id"]), ) if not target_version: raise HTTPException(status_code=404, detail="Platform agent profile version not found") assistant = _resolve_assistant(account, target_version.get("assistant_id", ""), project["id"]) timestamp = now() update_sql = """ UPDATE platform_agent_profiles SET assistant_id = ?, name = ?, mission = ?, notes = ?, status = ?, config_json = ?, updated_at = ? WHERE id = ? """ update_params = ( (assistant or {}).get("id", ""), target_version.get("name", f"{legacy.platform_label(normalized_platform)} Agent"), target_version.get("mission", ""), target_version.get("notes", ""), target_version.get("status", "active"), target_version.get("config_json", "{}"), timestamp, row["id"], ) if (assistant or {}).get("id", ""): legacy.db.execute(update_sql, update_params) else: with legacy.db.session() as conn: conn.execute("PRAGMA foreign_keys=OFF") conn.execute(update_sql, update_params) conn.execute("PRAGMA foreign_keys=ON") updated_row = legacy.db.fetch_one("SELECT * FROM platform_agent_profiles WHERE id = ?", (row["id"],)) assert updated_row is not None version = _create_platform_agent_profile_version( updated_row, actor_user_id=account["id"], source_type="user_rollback", reason=request.reason.strip() or f"回滚到版本 {target_version.get('version_no') or request.version_id}", rollback_from_version_id=target_version["id"], ) _log_platform_agent_profile_audit( profile_id=updated_row["id"], version_id=version["id"], actor_user_id=account["id"], action_key="rollback-platform-agent-profile", summary=f"已回滚 {legacy.platform_label(normalized_platform)} Agent 配置到版本 {target_version.get('version_no') or request.version_id}", details={"project_id": project["id"], "platform": normalized_platform, "rollback_to_version_id": target_version["id"]}, ) return _platform_agent_payload(account, updated_row, platform=normalized_platform, project_id=project["id"]) @app.get("/v2/platform-agents/{platform}/memories") def list_platform_memories( platform: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) rows = legacy.db.fetch_all( """ SELECT * FROM agent_memories WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY updated_at DESC """, (account["id"], project["id"], normalized_platform), ) items = [_memory_payload(row) for row in rows] return {"items": items, "count": len(items)} @app.post("/v2/platform-agents/{platform}/memories") def upsert_platform_memory( platform: str, request: AgentMemoryUpsertRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _upsert_memory(account, agent_scope="platform", platform=normalized_platform, request=request) @app.get("/v2/platform-agents/{platform}/skills") def list_platform_skills( platform: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) rows = legacy.db.fetch_all( """ SELECT * FROM agent_skills WHERE user_id = ? AND project_id = ? AND agent_scope = 'platform' AND platform = ? ORDER BY updated_at DESC """, (account["id"], project["id"], normalized_platform), ) items = [_skill_payload(row) for row in rows] return {"items": items, "count": len(items)} @app.post("/v2/platform-agents/{platform}/skills") def create_platform_skill( platform: str, request: AgentSkillUpsertRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _upsert_skill(account, agent_scope="platform", platform=normalized_platform, request=request) @app.patch("/v2/platform-agents/{platform}/skills/{skill_id}") def update_platform_skill( platform: str, skill_id: str, request: AgentSkillUpsertRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _upsert_skill(account, agent_scope="platform", platform=normalized_platform, request=request, skill_id=skill_id) @app.post("/v2/platform-agents/{platform}/self-check") def run_platform_agent_self_check( platform: str, request: PlatformAgentSelfCheckRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _platform_self_check( account, platform=normalized_platform, project_id=request.project_id, sample_limit=request.sample_limit, remember_summary=request.remember_summary, ) @app.post("/v2/platform-agents/{platform}/skills/{skill_id}/review") def review_platform_skill( platform: str, skill_id: str, request: PlatformSkillReviewRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _review_platform_skill(account, platform=normalized_platform, skill_id=skill_id, request=request) @app.get("/v2/platform-agents/{platform}/skills/{skill_id}/versions") def list_platform_skill_versions( platform: str, skill_id: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) normalized_platform = _safe_platform(platform) items = _list_skill_versions(account, platform=normalized_platform, project_id=project["id"], skill_id=skill_id) return {"items": items, "count": len(items)} @app.post("/v2/platform-agents/{platform}/skills/{skill_id}/rollback") def rollback_platform_skill( platform: str, skill_id: str, request: PlatformSkillRollbackRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: normalized_platform = _safe_platform(platform) return _rollback_platform_skill(account, platform=normalized_platform, skill_id=skill_id, request=request) @app.get("/v2/oneliner/governance/effective") def get_effective_oneliner_governance( project_id: str | None = Query(default=None), platform: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) return _effective_policy_payload( subject_account=account, subject_project_id=(project or {}).get("id", ""), platform=platform or "", ) @app.get("/v2/oneliner/governance/user/global") def get_user_global_policy( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) resolved_project_id = (project or {}).get("id", "") scope_row = _policy_scope_row( scope_kind="user_global", subject_user_id=account["id"], subject_project_id=resolved_project_id, ) payload = _bundle_with_versions( scope_row, fallback_kind="user_global", fallback_user_id=account["id"], fallback_project_id=resolved_project_id, active_version_only=True, ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=resolved_project_id, platform="", )["effective_policy"] return payload @app.put("/v2/oneliner/governance/user/global") def put_user_global_policy( request: AgentPolicyUpsertRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) scope_row = _ensure_policy_scope( scope_kind="user_global", subject_user_id=account["id"], subject_project_id=project["id"], title=request.title, summary=request.summary, ) payload = _create_policy_version( scope_row, actor_user_id=account["id"], title=request.title, summary=request.summary, policy=request.policy, effect_mode=request.effect_mode, starts_at=request.starts_at, ends_at=request.ends_at, config=request.config, reason=request.reason, source_type="user", ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform="", )["effective_policy"] payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=account["id"], action_key="publish-user-global-policy", summary=f"已更新用户全局策略:{payload['scope']['title']}", details={"project_id": project["id"]}, ) return payload @app.get("/v2/oneliner/governance/user/global/versions") def list_user_global_policy_versions( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) scope_row = _policy_scope_row( scope_kind="user_global", subject_user_id=account["id"], subject_project_id=(project or {}).get("id", ""), ) items = _list_policy_versions(scope_row) return {"items": items, "count": len(items)} @app.get("/v2/oneliner/governance/user/audits") def list_user_policy_audits( project_id: str | None = Query(default=None), platform: str = Query(default=""), limit: int = Query(default=20, ge=1, le=100), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) resolved_project_id = (project or {}).get("id", "") normalized_platform = _normalize_policy_platform(platform) where_clauses = [ "WHERE scope.subject_user_id = ?", "AND (scope.subject_project_id = ? OR scope.subject_project_id = '')", ] params: list[Any] = [account["id"], resolved_project_id] if normalized_platform: where_clauses.append("AND (scope.platform = '' OR scope.platform = ?)") params.append(normalized_platform) items = _fetch_policy_audit_records(" ".join(where_clauses), tuple(params), limit=limit, public_view=True) return {"items": items, "count": len(items)} @app.post("/v2/oneliner/governance/user/global/rollback") def rollback_user_global_policy( request: AgentPolicyRollbackRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) scope_row = _policy_scope_row( scope_kind="user_global", subject_user_id=account["id"], subject_project_id=project["id"], ) if not scope_row: raise HTTPException(status_code=404, detail="Policy scope not found") payload = _rollback_policy_scope( scope_row, actor_user_id=account["id"], version_id=request.version_id, reason=request.reason, source_type="user_rollback", ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform="", )["effective_policy"] payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=account["id"], action_key="rollback-user-global-policy", summary=f"已回滚用户全局策略:{payload['scope']['title']}", details={"project_id": project["id"], "rollback_to_version_id": request.version_id}, ) return payload @app.get("/v2/oneliner/governance/user/platforms/{platform}") def get_user_platform_policy( platform: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) resolved_project_id = (project or {}).get("id", "") normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row( scope_kind="user_platform", subject_user_id=account["id"], subject_project_id=resolved_project_id, platform=normalized_platform, ) payload = _bundle_with_versions( scope_row, fallback_kind="user_platform", fallback_platform=normalized_platform, fallback_user_id=account["id"], fallback_project_id=resolved_project_id, active_version_only=True, ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=resolved_project_id, platform=normalized_platform, )["effective_policy"] return payload @app.put("/v2/oneliner/governance/user/platforms/{platform}") def put_user_platform_policy( platform: str, request: AgentPolicyUpsertRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = _normalize_policy_platform(platform) scope_row = _ensure_policy_scope( scope_kind="user_platform", subject_user_id=account["id"], subject_project_id=project["id"], platform=normalized_platform, title=request.title, summary=request.summary, ) payload = _create_policy_version( scope_row, actor_user_id=account["id"], title=request.title, summary=request.summary, policy=request.policy, effect_mode=request.effect_mode, starts_at=request.starts_at, ends_at=request.ends_at, config=request.config, reason=request.reason, source_type="user", ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform=normalized_platform, )["effective_policy"] payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=account["id"], action_key="publish-user-platform-policy", summary=f"已更新 {legacy.platform_label(normalized_platform)} 用户平台策略", details={"project_id": project["id"], "platform": normalized_platform}, ) return payload @app.get("/v2/oneliner/governance/user/platforms/{platform}/versions") def list_user_platform_policy_versions( platform: str, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project_for_read(account, project_id or None) normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row( scope_kind="user_platform", subject_user_id=account["id"], subject_project_id=(project or {}).get("id", ""), platform=normalized_platform, ) items = _list_policy_versions(scope_row) return {"items": items, "count": len(items)} @app.post("/v2/oneliner/governance/user/platforms/{platform}/rollback") def rollback_user_platform_policy( platform: str, request: AgentPolicyRollbackRequest, account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, request.project_id or None) normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row( scope_kind="user_platform", subject_user_id=account["id"], subject_project_id=project["id"], platform=normalized_platform, ) if not scope_row: raise HTTPException(status_code=404, detail="Policy scope not found") payload = _rollback_policy_scope( scope_row, actor_user_id=account["id"], version_id=request.version_id, reason=request.reason, source_type="user_rollback", ) payload["effective_policy"] = _effective_policy_payload( subject_account=account, subject_project_id=project["id"], platform=normalized_platform, )["effective_policy"] payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=account["id"], action_key="rollback-user-platform-policy", summary=f"已回滚 {legacy.platform_label(normalized_platform)} 用户平台策略", details={"project_id": project["id"], "platform": normalized_platform, "rollback_to_version_id": request.version_id}, ) return payload @app.get("/v2/admin/oneliner/governance/system/main-agent") def get_system_main_policy(admin: dict[str, Any] = Depends(legacy.require_super_admin)) -> dict[str, Any]: _ = admin scope_row = _policy_scope_row(scope_kind="system_main") return _bundle_with_versions(scope_row, fallback_kind="system_main", active_version_only=True) @app.put("/v2/admin/oneliner/governance/system/main-agent") def put_system_main_policy( request: AgentPolicyUpsertRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: scope_row = _ensure_policy_scope( scope_kind="system_main", title=request.title, summary=request.summary, ) payload = _create_policy_version( scope_row, actor_user_id=admin["id"], title=request.title, summary=request.summary, policy=request.policy, effect_mode=request.effect_mode, starts_at=request.starts_at, ends_at=request.ends_at, config=request.config, reason=request.reason, source_type="system", ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="publish-system-main-policy", summary=f"已发布系统主 Agent 策略:{payload['scope']['title']}", ) return payload @app.get("/v2/admin/oneliner/governance/system/main-agent/versions") def list_system_main_policy_versions(admin: dict[str, Any] = Depends(legacy.require_super_admin)) -> dict[str, Any]: _ = admin scope_row = _policy_scope_row(scope_kind="system_main") items = _list_policy_versions(scope_row) return {"items": items, "count": len(items)} @app.post("/v2/admin/oneliner/governance/system/main-agent/rollback") def rollback_system_main_policy( request: AgentPolicyRollbackRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: scope_row = _policy_scope_row(scope_kind="system_main") if not scope_row: raise HTTPException(status_code=404, detail="Policy scope not found") payload = _rollback_policy_scope( scope_row, actor_user_id=admin["id"], version_id=request.version_id, reason=request.reason, source_type="admin_rollback", ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="rollback-system-main-policy", summary=f"已回滚系统主 Agent 策略:{payload['scope']['title']}", details={"rollback_to_version_id": request.version_id}, ) return payload @app.get("/v2/admin/oneliner/governance/system/platforms/{platform}") def get_system_platform_policy( platform: str, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row(scope_kind="system_platform", platform=normalized_platform) return _bundle_with_versions( scope_row, fallback_kind="system_platform", fallback_platform=normalized_platform, active_version_only=True, ) @app.put("/v2/admin/oneliner/governance/system/platforms/{platform}") def put_system_platform_policy( platform: str, request: AgentPolicyUpsertRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: normalized_platform = _normalize_policy_platform(platform) scope_row = _ensure_policy_scope( scope_kind="system_platform", platform=normalized_platform, title=request.title, summary=request.summary, ) payload = _create_policy_version( scope_row, actor_user_id=admin["id"], title=request.title, summary=request.summary, policy=request.policy, effect_mode=request.effect_mode, starts_at=request.starts_at, ends_at=request.ends_at, config=request.config, reason=request.reason, source_type="system", ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="publish-system-platform-policy", summary=f"已发布 {legacy.platform_label(normalized_platform)} 系统平台策略", details={"platform": normalized_platform}, ) return payload @app.get("/v2/admin/oneliner/governance/system/platforms/{platform}/versions") def list_system_platform_policy_versions( platform: str, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row(scope_kind="system_platform", platform=normalized_platform) items = _list_policy_versions(scope_row) return {"items": items, "count": len(items)} @app.post("/v2/admin/oneliner/governance/system/platforms/{platform}/rollback") def rollback_system_platform_policy( platform: str, request: AgentPolicyRollbackRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row(scope_kind="system_platform", platform=normalized_platform) if not scope_row: raise HTTPException(status_code=404, detail="Policy scope not found") payload = _rollback_policy_scope( scope_row, actor_user_id=admin["id"], version_id=request.version_id, reason=request.reason, source_type="admin_rollback", ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="rollback-system-platform-policy", summary=f"已回滚 {legacy.platform_label(normalized_platform)} 系统平台策略", details={"platform": normalized_platform, "rollback_to_version_id": request.version_id}, ) return payload @app.get("/v2/admin/oneliner/governance/directory") def get_admin_governance_directory( admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin return _governance_directory_payload() @app.get("/v2/admin/oneliner/governance/audits") def list_admin_governance_audits( target_user_id: str = Query(default=""), target_project_id: str = Query(default=""), platform: str = Query(default=""), include_system: bool = Query(default=False), limit: int = Query(default=30, ge=1, le=100), admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin normalized_platform = _normalize_policy_platform(platform) clauses: list[str] = [] params: list[Any] = [] if target_user_id.strip(): target_parts = ["(scope.subject_user_id = ?"] params.append(target_user_id.strip()) if target_project_id.strip(): target_parts.append("AND (scope.subject_project_id = ? OR scope.subject_project_id = '')") params.append(target_project_id.strip()) if normalized_platform: target_parts.append("AND (scope.platform = '' OR scope.platform = ?)") params.append(normalized_platform) target_parts.append(")") clauses.append(" ".join(target_parts)) if include_system: if normalized_platform: clauses.append("(scope.scope_kind = 'system_main' OR (scope.scope_kind = 'system_platform' AND scope.platform = ?))") params.append(normalized_platform) else: clauses.append("(scope.scope_kind IN ('system_main', 'system_platform'))") where_sql = "WHERE 1 = 1" if not clauses else "WHERE " + " OR ".join(f"({clause})" for clause in clauses) items = _fetch_policy_audit_records(where_sql, tuple(params), limit=limit) return {"items": items, "count": len(items)} @app.get("/v2/admin/oneliner/governance/overrides") def get_admin_override_policy( target_user_id: str = Query(default=""), target_project_id: str = Query(default=""), platform: str | None = Query(default=None), admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin if not target_user_id.strip(): raise HTTPException(status_code=400, detail="target_user_id is required") subject_account = _load_policy_subject_account(target_user_id.strip()) subject_project_id = "" if target_project_id.strip(): subject_project_id = _load_policy_subject_project(user_id=subject_account["id"], project_id=target_project_id.strip())["id"] normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, ) payload = _bundle_with_versions( scope_row, fallback_kind="admin_override", fallback_platform=normalized_platform, fallback_user_id=subject_account["id"], fallback_project_id=subject_project_id, active_version_only=True, ) payload.update( _effective_policy_payload( subject_account=subject_account, subject_project_id=subject_project_id, platform=normalized_platform, ) ) return payload @app.post("/v2/admin/oneliner/governance/overrides") def put_admin_override_policy( request: AgentPolicyUpsertRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: if not request.target_user_id.strip(): raise HTTPException(status_code=400, detail="target_user_id is required") subject_account = _load_policy_subject_account(request.target_user_id.strip()) subject_project_id = "" if request.target_project_id.strip(): subject_project_id = _load_policy_subject_project(user_id=subject_account["id"], project_id=request.target_project_id.strip())["id"] normalized_platform = _normalize_policy_platform(request.platform) scope_row = _ensure_policy_scope( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, title=request.title, summary=request.summary, ) payload = _create_policy_version( scope_row, actor_user_id=admin["id"], title=request.title, summary=request.summary, policy=request.policy, effect_mode=request.effect_mode, starts_at=request.starts_at, ends_at=request.ends_at, config=request.config, reason=request.reason, source_type="admin_override", ) payload.update( _effective_policy_payload( subject_account=subject_account, subject_project_id=subject_project_id, platform=normalized_platform, ) ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="publish-admin-override-policy", summary=f"已为 {subject_account.get('username') or subject_account['id']} 发布管理员覆盖策略", details={"target_user_id": subject_account["id"], "target_project_id": subject_project_id, "platform": normalized_platform}, ) return payload @app.get("/v2/admin/oneliner/governance/overrides/versions") def list_admin_override_versions( target_user_id: str = Query(default=""), target_project_id: str = Query(default=""), platform: str | None = Query(default=None), admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: _ = admin if not target_user_id.strip(): raise HTTPException(status_code=400, detail="target_user_id is required") subject_account = _load_policy_subject_account(target_user_id.strip()) subject_project_id = "" if target_project_id.strip(): subject_project_id = _load_policy_subject_project(user_id=subject_account["id"], project_id=target_project_id.strip())["id"] normalized_platform = _normalize_policy_platform(platform) scope_row = _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, ) items = _list_policy_versions(scope_row) return {"items": items, "count": len(items)} @app.post("/v2/admin/oneliner/governance/overrides/rollback") def rollback_admin_override_policy( request: AgentPolicyRollbackRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: if not request.target_user_id.strip(): raise HTTPException(status_code=400, detail="target_user_id is required") subject_account = _load_policy_subject_account(request.target_user_id.strip()) subject_project_id = "" if request.target_project_id.strip(): subject_project_id = _load_policy_subject_project(user_id=subject_account["id"], project_id=request.target_project_id.strip())["id"] normalized_platform = _normalize_policy_platform(request.platform) scope_row = _policy_scope_row( scope_kind="admin_override", subject_user_id=subject_account["id"], subject_project_id=subject_project_id, platform=normalized_platform, ) if not scope_row: raise HTTPException(status_code=404, detail="Policy scope not found") payload = _rollback_policy_scope( scope_row, actor_user_id=admin["id"], version_id=request.version_id, reason=request.reason, source_type="admin_rollback", ) payload.update( _effective_policy_payload( subject_account=subject_account, subject_project_id=subject_project_id, platform=normalized_platform, ) ) payload["audit"] = _log_policy_audit( scope_id=payload["scope"]["id"], version_id=(payload.get("current_version") or {}).get("id", ""), actor_user_id=admin["id"], action_key="rollback-admin-override-policy", summary=f"已回滚 {subject_account.get('username') or subject_account['id']} 的管理员覆盖策略", details={"target_user_id": subject_account["id"], "target_project_id": subject_project_id, "platform": normalized_platform, "rollback_to_version_id": request.version_id}, ) return payload @app.get("/v2/tenant/quota") def get_tenant_quota( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) return _get_tenant_quota(account, project_id=project["id"]) @app.put("/v2/tenant/quota") def put_tenant_quota( request: TenantQuotaRequest, project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) existing = _get_tenant_quota_row(account, project_id=project["id"]) timestamp = now() request_config = dict(request.config or {}) requested_package_label = _normalize_package_label(request.package_label or request_config.get("package_label")) package_label = requested_package_label if requested_package_label in TENANT_QUOTA_PACKAGE_PRESETS else "custom" warn_threshold_value = _clamp_warn_threshold( request_config.get("warn_threshold", 0.8), TENANT_QUOTA_PACKAGE_PRESETS.get(package_label, {}).get("warn_threshold", 0.8), ) normalized_config = dict(request_config) normalized_config["package_label"] = package_label normalized_config["warn_threshold"] = warn_threshold_value quota_values = _tenant_quota_values(request, package_label) if existing: legacy.db.execute( """ UPDATE tenant_quota_profiles SET monthly_budget_cents = ?, storage_limit_bytes = ?, analysis_quota = ?, copy_quota = ?, ai_video_quota = ?, real_cut_quota = ?, recorder_quota = ?, enabled = ?, config_json = ?, updated_at = ? WHERE id = ? """, ( quota_values["monthly_budget_cents"], quota_values["storage_limit_bytes"], quota_values["analysis_quota"], quota_values["copy_quota"], quota_values["ai_video_quota"], quota_values["real_cut_quota"], quota_values["recorder_quota"], 1 if request.enabled else 0, _dump(normalized_config), timestamp, existing["id"], ), ) else: quota_id = make_id("quota") legacy.db.execute( """ INSERT INTO tenant_quota_profiles ( id, user_id, project_id, monthly_budget_cents, storage_limit_bytes, analysis_quota, copy_quota, ai_video_quota, real_cut_quota, recorder_quota, enabled, config_json, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( quota_id, account["id"], project["id"], quota_values["monthly_budget_cents"], quota_values["storage_limit_bytes"], quota_values["analysis_quota"], quota_values["copy_quota"], quota_values["ai_video_quota"], quota_values["real_cut_quota"], quota_values["recorder_quota"], 1 if request.enabled else 0, _dump(normalized_config), timestamp, timestamp, ), ) return _get_tenant_quota(account, project_id=project["id"]) @app.get("/v2/tenant/usage") def get_tenant_usage( project_id: str | None = Query(default=None), account: dict[str, Any] = Depends(legacy.require_approved), ) -> dict[str, Any]: project = _resolve_project(account, project_id or None) return _tenant_usage_summary(account, project_id=project["id"]) @app.get("/v2/admin/ops/overview") def admin_ops_overview(admin: dict[str, Any] = Depends(legacy.require_super_admin)) -> dict[str, Any]: return _admin_ops_overview_payload(admin) @app.get("/v2/admin/ops/fix-runs") def admin_ops_fix_runs(admin: dict[str, Any] = Depends(legacy.require_super_admin)) -> dict[str, Any]: rows = legacy.db.fetch_all( "SELECT * FROM admin_ops_fix_runs ORDER BY updated_at DESC LIMIT 50" ) items = [_fix_run_payload(row) for row in rows] return {"items": items, "count": len(items)} @app.post("/v2/admin/ops/incidents/scan") def admin_ops_scan(admin: dict[str, Any] = Depends(legacy.require_super_admin)) -> dict[str, Any]: return _scan_admin_incidents(admin) @app.post("/v2/admin/ops/incidents/{incident_id}/repair-plan") def create_admin_repair_plan( incident_id: str, request: AdminFixPlanRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: incident_row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (incident_id,)) if not incident_row: raise HTTPException(status_code=404, detail="Incident not found") incident = _incident_payload(incident_row) payload = _create_fix_run( admin, incident=incident, scope=request.scope.strip() or "plan", notes=request.notes, ) payload["audit"] = _log_admin_audit_event( actor_user_id=admin["id"], incident_id=incident_id, action_key="repair-plan", status="planned", summary=f"已为事件「{incident.get('title') or incident_id}」生成修复计划。", details={"fix_run_id": payload["id"], "scope": payload.get("plan_scope", "plan")}, ) return payload @app.patch("/v2/admin/ops/incidents/{incident_id}") def review_admin_incident( incident_id: str, request: AdminIncidentReviewRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: current = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (incident_id,)) if not current: raise HTTPException(status_code=404, detail="Incident not found") timestamp = now() legacy.db.execute( """ UPDATE admin_ops_incidents SET status = ?, reviewed_by = ?, review_notes = ?, updated_at = ? WHERE id = ? """, ( request.status.strip() or "reviewed", admin["id"], request.review_notes.strip(), timestamp, incident_id, ), ) row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (incident_id,)) payload = _incident_payload(row) payload["audit"] = _log_admin_audit_event( actor_user_id=admin["id"], incident_id=incident_id, action_key="review", status=payload.get("status", "reviewed"), summary=f"事件「{payload.get('title', incident_id)}」已更新为 {payload.get('status', 'reviewed')}。", details={ "review_notes": request.review_notes.strip(), "severity": payload.get("severity", ""), "source_type": payload.get("source_type", ""), }, ) return payload @app.post("/v2/admin/ops/fix-runs/{run_id}/audit") def audit_admin_fix_run( run_id: str, request: AdminFixRunReviewRequest, admin: dict[str, Any] = Depends(legacy.require_super_admin), ) -> dict[str, Any]: current = legacy.db.fetch_one("SELECT * FROM admin_ops_fix_runs WHERE id = ?", (run_id,)) if not current: raise HTTPException(status_code=404, detail="Fix run not found") incident_row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (current["incident_id"],)) review_status = request.review_status.strip() or "approved" timestamp = now() next_status = "audited" if review_status in {"approved", "rejected"} else "watching" legacy.db.execute( """ UPDATE admin_ops_fix_runs SET audit_status = ?, review_notes = ?, status = ?, updated_at = ? WHERE id = ? """, ( review_status, request.review_notes.strip(), next_status, timestamp, run_id, ), ) if incident_row: incident_status = "resolved" if review_status == "approved" else "watching" if review_status == "watching" else "rejected" legacy.db.execute( """ UPDATE admin_ops_incidents SET status = ?, reviewed_by = ?, review_notes = ?, updated_at = ? WHERE id = ? """, ( incident_status, admin["id"], request.review_notes.strip(), timestamp, current["incident_id"], ), ) row = legacy.db.fetch_one("SELECT * FROM admin_ops_fix_runs WHERE id = ?", (run_id,)) payload = _fix_run_payload(row) payload["audit"] = _log_admin_audit_event( actor_user_id=admin["id"], incident_id=current["incident_id"], action_key="fix-run-audit", status=review_status, summary=f"修复计划 {run_id} 已审计为 {review_status}。", details={"review_notes": request.review_notes.strip()}, ) return payload