Files
storyforge/collector-service/app/oneliner_features.py
2026-03-23 16:01:24 +08:00

2787 lines
124 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 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)
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": "自定义任务",
}
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 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 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
);
"""
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 _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 _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 []
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],
}
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 {}
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 最近沉淀的方法与技能。")
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 '一条技能'}")
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": "",
}
)
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"],))
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,))
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()
if existing:
legacy.db.execute(
"""
UPDATE admin_ops_incidents
SET tenant_user_id = ?, tenant_project_id = ?, severity = ?, summary = ?, payload_json = ?, updated_at = ?
WHERE id = ?
""",
(
tenant_user_id,
tenant_project_id,
severity,
summary,
_dump(payload),
timestamp,
existing["id"],
),
)
row = legacy.db.fetch_one("SELECT * FROM admin_ops_incidents WHERE id = ?", (existing["id"],))
else:
incident_id = make_id("incident")
legacy.db.execute(
"""
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', '', '', '', ?, ?)
""",
(
incident_id,
tenant_user_id,
tenant_project_id,
source_type,
source_id,
severity,
title,
summary,
_dump(payload),
timestamp,
timestamp,
),
)
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 _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"
)
]
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),
"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,))
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)
if feedback_memory:
payload["feedback_memory"] = feedback_memory
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")
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(action_key)
if not executor:
raise HTTPException(status_code=400, detail=f"Unsupported OneLiner action: {action_key}")
result = await executor()
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,
"project_id": project["id"],
"platform": normalized_platform,
"executed_at": now(),
**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/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/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.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.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