Files
ewoooc/database/ai_models.py
ogt f2b20c1892
Some checks failed
CD Pipeline / deploy (push) Failing after 2m47s
fix: eliminate duplicate SQLAlchemy table definitions in ai_models.py
AgentContext/ActionPlan/ActionOutcome/AgentStrategyWeights were defined
in both ai_models.py and autoheal_models.py, causing:
  "Table 'agent_context' is already defined for this MetaData instance"
on every scheduler startup.

ai_models.py is now a pure re-export shim from autoheal_models.py.
autoheal_models.py remains the single source of truth (ADR-013).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 04:47:23 +08:00

126 lines
4.8 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.
# database/ai_models.py
# ⚠️ 這四個 class 的原始定義已移至 autoheal_models.pyADR-013 統一管理)。
# 此檔僅作向後相容 re-export shim不再重複定義 SQLAlchemy Table
# 以避免 "Table already defined for this MetaData instance" 衝突。
from .autoheal_models import ( # noqa: F401
AgentContext,
ActionPlan,
ActionOutcome,
AgentStrategyWeights,
)
# AI history and template models
from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, Float
from database.models import Base
from datetime import datetime
class AIGenerationHistory(Base):
"""
AI generation history tracking
"""
__tablename__ = 'ai_generation_history'
id = Column(Integer, primary_key=True, autoincrement=True)
generation_type = Column(String(50), nullable=False) # product_desc, marketing_copy, etc.
product_name = Column(String(200))
input_keywords = Column(Text) # JSON string
input_trend_topic = Column(String(500))
output_content = Column(Text)
generation_duration = Column(Float) # seconds
is_favorite = Column(Boolean, default=False)
is_used = Column(Boolean, default=False)
created_by = Column(String(100))
created_at = Column(DateTime, default=datetime.now)
def to_dict(self):
return {
'id': self.id,
'generation_type': self.generation_type,
'product_name': self.product_name,
'input_keywords': self.input_keywords,
'input_trend_topic': self.input_trend_topic,
'output_content': self.output_content,
'generation_duration': self.generation_duration,
'is_favorite': self.is_favorite,
'is_used': self.is_used,
'created_by': self.created_by,
'created_at': self.created_at.isoformat() if self.created_at else None
}
class AIPromptTemplate(Base):
"""
AI prompt templates
"""
__tablename__ = 'ai_prompt_templates'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(200), nullable=False)
description = Column(Text)
template_type = Column(String(50), nullable=False) # product_desc, marketing_copy, etc.
prompt_content = Column(Text, nullable=False)
variables = Column(Text) # JSON string of variable definitions
is_active = Column(Boolean, default=True)
is_system = Column(Boolean, default=False)
created_by = Column(String(100))
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'description': self.description,
'template_type': self.template_type,
'prompt_content': self.prompt_content,
'variables': self.variables,
'is_active': self.is_active,
'is_system': self.is_system,
'created_by': self.created_by,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None
}
class AIUsageTracking(Base):
"""
AI usage tracking for analytics and billing
"""
__tablename__ = 'ai_usage_tracking'
id = Column(Integer, primary_key=True, autoincrement=True)
user_id = Column(String(100))
session_id = Column(String(100))
service_type = Column(String(50), nullable=False) # openai, ollama, etc.
model_name = Column(String(100))
prompt_tokens = Column(Integer, default=0)
completion_tokens = Column(Integer, default=0)
total_tokens = Column(Integer, default=0)
cost_usd = Column(Float, default=0.0)
request_type = Column(String(50)) # generation, analysis, etc.
status = Column(String(20), default='success') # success, failed
error_message = Column(Text)
duration_ms = Column(Float)
created_at = Column(DateTime, default=datetime.now)
def to_dict(self):
return {
'id': self.id,
'user_id': self.user_id,
'session_id': self.session_id,
'service_type': self.service_type,
'model_name': self.model_name,
'prompt_tokens': self.prompt_tokens,
'completion_tokens': self.completion_tokens,
'total_tokens': self.total_tokens,
'cost_usd': self.cost_usd,
'request_type': self.request_type,
'status': self.status,
'error_message': self.error_message,
'duration_ms': self.duration_ms,
'created_at': self.created_at.isoformat() if self.created_at else None
}
__all__ = [
"AgentContext", "ActionPlan", "ActionOutcome", "AgentStrategyWeights",
"AIGenerationHistory", "AIPromptTemplate", "AIUsageTracking"
]