feat(trace): add session run isolation schema
This commit is contained in:
@@ -15,6 +15,7 @@ import java.time.LocalDateTime;
|
||||
@Entity
|
||||
@Table(name = "agent_step", indexes = {
|
||||
@Index(name = "idx_session_step", columnList = "session_id, step_index"),
|
||||
@Index(name = "idx_agent_step_run_step", columnList = "run_id, step_index"),
|
||||
@Index(name = "idx_agent_name", columnList = "agent_name")
|
||||
})
|
||||
@Data
|
||||
@@ -30,6 +31,9 @@ public class AgentStep {
|
||||
@Column(name = "session_id", nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
@Column(name = "run_id", length = 64)
|
||||
private String runId;
|
||||
|
||||
@Column(name = "step_index", nullable = false)
|
||||
private Integer stepIndex;
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.superbiz.agent.domain.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Chat session metadata entity.
|
||||
* Full message history remains in Redis SessionContext.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "chat_session", indexes = {
|
||||
@Index(name = "idx_chat_session_last_active", columnList = "last_active_at"),
|
||||
@Index(name = "idx_chat_session_status", columnList = "status"),
|
||||
@Index(name = "idx_chat_session_expires_at", columnList = "expires_at")
|
||||
})
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ChatSession {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "session_id", unique = true, nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
@Column(name = "status", length = 16)
|
||||
private String status = "ACTIVE";
|
||||
|
||||
@Column(name = "message_pair_count")
|
||||
private Integer messagePairCount = 0;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "last_active_at")
|
||||
private LocalDateTime lastActiveAt;
|
||||
|
||||
@Column(name = "expires_at")
|
||||
private LocalDateTime expiresAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
createdAt = now;
|
||||
if (lastActiveAt == null) {
|
||||
lastActiveAt = now;
|
||||
}
|
||||
if (status == null) {
|
||||
status = "ACTIVE";
|
||||
}
|
||||
if (messagePairCount == null) {
|
||||
messagePairCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.superbiz.agent.domain.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* One diagnosis execution run.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "diagnosis_run", indexes = {
|
||||
@Index(name = "idx_diagnosis_run_session_created", columnList = "session_id, created_at, id"),
|
||||
@Index(name = "idx_diagnosis_run_session_run", columnList = "session_id, run_id"),
|
||||
@Index(name = "idx_diagnosis_run_status", columnList = "status"),
|
||||
@Index(name = "idx_diagnosis_run_agent_flow", columnList = "agent_flow")
|
||||
})
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DiagnosisRun {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "run_id", unique = true, nullable = false, length = 64)
|
||||
private String runId;
|
||||
|
||||
@Column(name = "session_id", nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
@Column(name = "query", nullable = false, columnDefinition = "TEXT")
|
||||
private String query;
|
||||
|
||||
@Column(name = "status", length = 16)
|
||||
private String status = "PENDING";
|
||||
|
||||
@Column(name = "agent_flow", length = 32)
|
||||
private String agentFlow;
|
||||
|
||||
@Column(name = "answer", columnDefinition = "LONGTEXT")
|
||||
private String answer;
|
||||
|
||||
@JdbcTypeCode(SqlTypes.JSON)
|
||||
@Column(name = "self_evaluation", columnDefinition = "JSON")
|
||||
private String selfEvaluation;
|
||||
|
||||
@Column(name = "feedback", length = 16)
|
||||
private String feedback;
|
||||
|
||||
@Column(name = "total_duration_ms")
|
||||
private Integer totalDurationMs;
|
||||
|
||||
@Column(name = "total_token_count")
|
||||
private Integer totalTokenCount;
|
||||
|
||||
@Column(name = "step_count")
|
||||
private Integer stepCount;
|
||||
|
||||
@Column(name = "tool_call_count")
|
||||
private Integer toolCallCount;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@PrePersist
|
||||
protected void onCreate() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
createdAt = now;
|
||||
updatedAt = now;
|
||||
if (status == null) {
|
||||
status = "PENDING";
|
||||
}
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void onUpdate() {
|
||||
updatedAt = LocalDateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.time.LocalDateTime;
|
||||
@Entity
|
||||
@Table(name = "tool_invocation", indexes = {
|
||||
@Index(name = "idx_session_id", columnList = "session_id"),
|
||||
@Index(name = "idx_tool_invocation_run_id", columnList = "run_id, id"),
|
||||
@Index(name = "idx_tool_name", columnList = "tool_name"),
|
||||
@Index(name = "idx_retrieval_layer", columnList = "retrieval_layer")
|
||||
})
|
||||
@@ -33,6 +34,9 @@ public class ToolInvocation {
|
||||
@Column(name = "session_id", nullable = false, length = 64)
|
||||
private String sessionId;
|
||||
|
||||
@Column(name = "run_id", length = 64)
|
||||
private String runId;
|
||||
|
||||
@Column(name = "step_id")
|
||||
private Long stepId;
|
||||
|
||||
|
||||
@@ -22,8 +22,18 @@ public interface AgentStepRepository extends JpaRepository<AgentStep, Long> {
|
||||
*/
|
||||
List<AgentStep> findBySessionId(String sessionId);
|
||||
|
||||
/**
|
||||
* 根据运行ID查询所有步骤(按步骤号排序)。
|
||||
*/
|
||||
List<AgentStep> findByRunIdOrderByStepIndex(String runId);
|
||||
|
||||
/**
|
||||
* 统计某个会话的步骤数
|
||||
*/
|
||||
int countBySessionId(String sessionId);
|
||||
|
||||
/**
|
||||
* 统计某个运行的步骤数。
|
||||
*/
|
||||
int countByRunId(String runId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.superbiz.agent.repository;
|
||||
|
||||
import com.superbiz.agent.domain.entity.ChatSession;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface ChatSessionRepository extends JpaRepository<ChatSession, Long> {
|
||||
|
||||
Optional<ChatSession> findBySessionId(String sessionId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.superbiz.agent.repository;
|
||||
|
||||
import com.superbiz.agent.domain.entity.DiagnosisRun;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface DiagnosisRunRepository extends JpaRepository<DiagnosisRun, Long> {
|
||||
|
||||
Optional<DiagnosisRun> findByRunId(String runId);
|
||||
|
||||
Optional<DiagnosisRun> findBySessionIdAndRunId(String sessionId, String runId);
|
||||
|
||||
Optional<DiagnosisRun> findFirstBySessionIdOrderByCreatedAtDescIdDesc(String sessionId);
|
||||
|
||||
List<DiagnosisRun> findBySessionIdOrderByCreatedAtDescIdDesc(String sessionId);
|
||||
}
|
||||
|
||||
@@ -22,11 +22,21 @@ public interface ToolInvocationRepository extends JpaRepository<ToolInvocation,
|
||||
*/
|
||||
List<ToolInvocation> findBySessionIdOrderByIdAsc(String sessionId);
|
||||
|
||||
/**
|
||||
* 根据运行ID按创建顺序查询所有工具调用
|
||||
*/
|
||||
List<ToolInvocation> findByRunIdOrderByIdAsc(String runId);
|
||||
|
||||
/**
|
||||
* 根据会话ID统计真实工具调用次数
|
||||
*/
|
||||
long countBySessionId(String sessionId);
|
||||
|
||||
/**
|
||||
* 根据运行ID统计真实工具调用次数
|
||||
*/
|
||||
long countByRunId(String runId);
|
||||
|
||||
/**
|
||||
* 根据工具名查询所有调用
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user