Files
storyforge/collector-service/app/oneliner_features.py
2026-03-29 16:42:12 +08:00

5192 lines
226 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
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)
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)
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):
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 = ""
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},
},
"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"},
}
ACTION_USAGE_KEYS: dict[str, str] = {
"generate-copy": "copy",
"review-draft": "review",
"import-homepage": "content_source_sync",
"analyze-top-videos": "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 _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_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 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 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_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 _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"
legacy.db.execute(
"""
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
profile_id,
account["id"],
project_id,
assistant_id,
"OneLiner",
"",
"",
default_platform,
_dump({"chat_only_for_unreleased_ui": True}),
created_at,
created_at,
),
)
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 = "待补全"
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,
"readiness_score": readiness_score,
"readiness_label": readiness_label,
"assistant": assistant,
"created_at": (row or {}).get("created_at", ""),
"updated_at": (row or {}).get("updated_at", ""),
}
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 _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_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 _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 _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"),
}
)
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,
}
def _bundle_with_versions(
scope_row: dict[str, Any] | None,
*,
fallback_kind: str,
fallback_platform: str = "",
fallback_user_id: str = "",
fallback_project_id: str = "",
) -> 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,
)
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 {}
return {
"id": data.get("id", ""),
"user_id": data.get("user_id", ""),
"project_id": data.get("project_id", ""),
"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": _parse_json(data.get("config_json"), {}),
"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 _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 _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": _profile_payload(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"],
),
"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"],
) 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 "")
platform_agent = context.get("platform_agent") 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 []
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.get("assistant", {}).get("name"):
next_steps.append(f"默认调度 {platform_agent['assistant']['name']} 作为执行 Agent。")
if evidence:
next_steps.append("我会优先参考该平台 Agent 最近沉淀的方法与技能。")
if governance_layers:
next_steps.append(f"当前会话已叠加 {len(governance_layers)} 层策略,我会先按生效策略执行。")
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 已绑定:{context['platform_agent'].get('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("当前策略层要求管理员复核,所以我会把高风险动作先压成待确认。")
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-top-videos",
"platform": plan.get("platform", ""),
"payload": {
"target_account_id": latest_platform_account["id"],
},
}
)
if context.get("assistant"):
secondary_actions.append(
{
"key": "run-oneliner-action",
"label": "直接生成一版文案",
"kind": "api_action",
"executor_key": "generate-copy",
"platform": plan.get("platform", ""),
}
)
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": "",
}
)
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.get("assistant", {}).get("name") or context.get("assistant", {}).get("name") or "",
"readiness_label": platform_agent.get("readiness_label") or "",
"readiness_score": platform_agent.get("readiness_score") or 0,
"primary_action": primary_action or {},
"blocked_reason": blocked_reason,
"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()
if existing:
legacy.db.execute(
"""
UPDATE platform_agent_profiles
SET assistant_id = ?, name = ?, mission = ?, notes = ?, status = ?, config_json = ?, updated_at = ?
WHERE id = ?
""",
(
(assistant or {}).get("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"],
),
)
row = legacy.db.fetch_one("SELECT * FROM platform_agent_profiles WHERE id = ?", (existing["id"],))
else:
profile_id = make_id("plat_agent")
legacy.db.execute(
"""
INSERT INTO platform_agent_profiles (
id, user_id, project_id, platform, assistant_id, name, mission, notes, status, config_json, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
profile_id,
account["id"],
project["id"],
platform,
(assistant or {}).get("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,
),
)
row = legacy.db.fetch_one("SELECT * FROM platform_agent_profiles WHERE id = ?", (profile_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 {}
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,
}
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,
}
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,
}
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,
}
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,
}
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,
}
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,
}
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", ""),
},
}
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,
},
}
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 视频。"
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)),
),
account,
)
return {
"title": "OneLiner 已创建 AI 视频任务",
"summary": f"已基于「{source_job.get('title') or source_job['id']}」创建 AI 视频任务。",
"payload": {
"job": job,
"source_job": legacy.job_payload(source_job),
"brief": brief,
},
}
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),
},
}
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,
},
}
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-top-videos": _run_analyze_top_videos,
"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.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 _profile_payload(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()
legacy.db.execute(
"""
UPDATE oneliner_profiles
SET assistant_id = ?, display_name = ?, long_term_goal = ?, notes = ?, default_platform = ?, config_json = ?, updated_at = ?
WHERE id = ?
""",
(
(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"],
),
)
row = legacy.db.fetch_one("SELECT * FROM oneliner_profiles WHERE id = ?", (existing["id"],))
return _profile_payload(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}/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(account, project_id or None)
return _effective_policy_payload(
subject_account=account,
subject_project_id=project["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(account, project_id or None)
scope_row = _policy_scope_row(
scope_kind="user_global",
subject_user_id=account["id"],
subject_project_id=project["id"],
)
payload = _bundle_with_versions(
scope_row,
fallback_kind="user_global",
fallback_user_id=account["id"],
fallback_project_id=project["id"],
)
payload["effective_policy"] = _effective_policy_payload(
subject_account=account,
subject_project_id=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(account, project_id or None)
scope_row = _policy_scope_row(
scope_kind="user_global",
subject_user_id=account["id"],
subject_project_id=project["id"],
)
items = _list_policy_versions(scope_row)
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(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["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=project["id"],
)
payload["effective_policy"] = _effective_policy_payload(
subject_account=account,
subject_project_id=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(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["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")
@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,
)
@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/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,
)
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()
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 = ?
""",
(
request.monthly_budget_cents,
request.storage_limit_bytes,
request.analysis_quota,
request.copy_quota,
request.ai_video_quota,
request.real_cut_quota,
request.recorder_quota,
1 if request.enabled else 0,
_dump(request.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"],
request.monthly_budget_cents,
request.storage_limit_bytes,
request.analysis_quota,
request.copy_quota,
request.ai_video_quota,
request.real_cut_quota,
request.recorder_quota,
1 if request.enabled else 0,
_dump(request.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