from django.db import models class Session(models.Model): session_id = models.CharField(max_length=64) agent_name = models.CharField(max_length=128) source_node = models.CharField(max_length=64) session_version = models.IntegerField(default=0) model_provider = models.CharField(max_length=64, blank=True, default="") model_id = models.CharField(max_length=128, blank=True, default="") thinking_level = models.CharField(max_length=64, blank=True, default="") start_time = models.DateTimeField(null=True, blank=True) end_time = models.DateTimeField(null=True, blank=True) cwd = models.CharField(max_length=512, blank=True, default="") total_tokens = models.IntegerField(default=0) total_cost = models.FloatField(default=0.0) message_count = models.IntegerField(default=0) tool_call_count = models.IntegerField(default=0) error_count = models.IntegerField(default=0) raw_file_path = models.TextField(blank=True, default="") pushed_at = models.DateTimeField(null=True, blank=True) status = models.CharField(max_length=16, default="active") metadata = models.JSONField(default=dict, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "sessions" indexes = [ models.Index(fields=["session_id", "agent_name"], name="ses_sid_aname_idx"), ] ordering = ["-start_time"] def __str__(self): return f"Session({self.session_id} {self.agent_name})" class Message(models.Model): session = models.ForeignKey( Session, on_delete=models.CASCADE, related_name="messages" ) message_id = models.CharField(max_length=128) parent_id = models.CharField(max_length=128, blank=True, default="") seq = models.IntegerField(default=0) role = models.CharField(max_length=32) content_text = models.TextField(blank=True, default="") raw_content = models.JSONField(default=list, blank=True) raw_message = models.JSONField(default=dict, blank=True) timestamp = models.DateTimeField() model = models.CharField(max_length=128, blank=True, default="") provider = models.CharField(max_length=64, blank=True, default="") stop_reason = models.CharField(max_length=64, blank=True, default="") tokens_input = models.IntegerField(default=0) tokens_output = models.IntegerField(default=0) tokens_cache_read = models.IntegerField(default=0) tokens_cache_write = models.IntegerField(default=0) tokens_total = models.IntegerField(default=0) cost_total = models.FloatField(default=0.0) tool_call_id = models.CharField(max_length=128, blank=True, default="") tool_name = models.CharField(max_length=128, blank=True, default="") is_error = models.BooleanField(default=False) exit_code = models.IntegerField(null=True, blank=True) duration_ms = models.IntegerField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "messages" ordering = ["seq"] def __str__(self): return f"Message({self.message_id} {self.role})" class ToolCall(models.Model): session = models.ForeignKey( Session, on_delete=models.CASCADE, related_name="tool_calls" ) message = models.ForeignKey( Message, on_delete=models.CASCADE, related_name="tool_calls" ) tool_call_id = models.CharField(max_length=128) tool_name = models.CharField(max_length=128) arguments = models.JSONField(default=dict, blank=True) result_text = models.TextField(blank=True, default="") is_error = models.BooleanField(default=False) exit_code = models.IntegerField(null=True, blank=True) duration_ms = models.IntegerField(null=True, blank=True) seq = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "tool_calls" ordering = ["seq"] def __str__(self): return f"ToolCall({self.tool_name} {self.tool_call_id})"