生成记录接口兼容图片类型|CHAT对话生成视频/图片任务API+celery异步模块完成

This commit is contained in:
2026-05-27 13:11:55 +08:00
parent d61dcdc8db
commit b8eda53c0b
30 changed files with 3392 additions and 45 deletions
@@ -0,0 +1,134 @@
from __future__ import annotations
import hashlib
import json
from typing import Any
from app.models.base import async_session
from app.models.chat_generation_task_event import ChatGenerationTaskEvent
from app.models.chat_provider_call_log import ChatProviderCallLog
from app.utils.id_gen import generate_id
MAX_EXCERPT_CHARS = 2000
def _safe_json(data: Any) -> str | None:
if data is None:
return None
try:
return json.dumps(data, ensure_ascii=False, default=str)
except Exception:
return str(data)
def _excerpt(data: Any, limit: int = MAX_EXCERPT_CHARS) -> str | None:
text = _safe_json(data)
if text is None:
return None
# Avoid storing secrets in logs.
text = text.replace("Authorization", "Authorization-REDACTED")
text = text.replace("api_key", "api_key_REDACTED")
if len(text) > limit:
return text[:limit] + "...[truncated]"
return text
def _hash(data: Any) -> str | None:
text = _safe_json(data)
if text is None:
return None
return hashlib.sha256(text.encode("utf-8")).hexdigest()
async def log_task_event(
task: Any | None = None,
*,
record: Any | None = None,
task_id: str | None = None,
record_id: str | None = None,
event_type: str,
from_status: str | None = None,
to_status: str | None = None,
from_stage: str | None = None,
to_stage: str | None = None,
message: str | None = None,
detail: Any = None,
) -> None:
"""Write task event in a separate transaction; failure must not affect main flow."""
try:
obj = task or record
tid = task_id or record_id or (obj.id if obj else None)
if not tid:
return
async with async_session() as db:
db.add(ChatGenerationTaskEvent(
id=generate_id(),
task_id=tid,
generation_mode=getattr(obj, "generation_mode", "chatapi_async"),
event_type=event_type,
from_status=from_status,
to_status=to_status,
from_stage=from_stage,
to_stage=to_stage,
message=message,
detail_json=_excerpt(detail),
))
await db.commit()
except Exception:
return
async def log_provider_call(
task: Any | None = None,
*,
record: Any | None = None,
task_id: str | None = None,
record_id: str | None = None,
provider: str | None,
api_type: str,
model: str | None = None,
engine_id: str | None = None,
status: str,
latency_ms: int | None = None,
http_status: int | None = None,
provider_task_id: str | None = None,
request_data: Any = None,
response_data: Any = None,
prompt_tokens: int = 0,
completion_tokens: int = 0,
total_tokens: int = 0,
error_code: str | None = None,
error_message: str | None = None,
) -> None:
"""Write provider call log in a separate transaction; failure must not affect main flow."""
try:
obj = task or record
tid = task_id or record_id or (obj.id if obj else None)
if not tid:
return
async with async_session() as db:
db.add(ChatProviderCallLog(
id=generate_id(),
task_id=tid,
generation_mode=getattr(obj, "generation_mode", "chatapi_async"),
provider=provider,
api_type=api_type,
model=model,
engine_id=engine_id,
status=status,
latency_ms=latency_ms,
http_status=http_status,
provider_task_id=provider_task_id,
request_hash=_hash(request_data),
response_hash=_hash(response_data),
request_excerpt=_excerpt(request_data),
response_excerpt=_excerpt(response_data),
prompt_tokens=prompt_tokens or 0,
completion_tokens=completion_tokens or 0,
total_tokens=total_tokens or 0,
error_code=error_code,
error_message=error_message,
))
await db.commit()
except Exception:
return