feat(harness,rag): dual LLM audit fields, run conclusion, and hybrid quality
Persist provider reasoning and assistant text separately on agent_reasoning_audit (DeepSeekAssistantMessage path), extract diagnosis_run.conclusion, enrich RAG tool audit (step_id/query/qualityScore), gate empty mysql tools, drop devtools, and align MVP docs after live E2E verification.
This commit is contained in:
+45
-25
@@ -6,18 +6,21 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.superbiz.agent.domain.entity.ChatSession;
|
||||
import com.superbiz.agent.domain.entity.DiagnosisRun;
|
||||
import com.superbiz.agent.harness.audit.AgentStepAuditTracker;
|
||||
import com.superbiz.agent.harness.audit.ModelCallComponent;
|
||||
import com.superbiz.agent.harness.audit.RunConclusionExtractor;
|
||||
import com.superbiz.agent.harness.contract.IntentType;
|
||||
import com.superbiz.agent.harness.contract.PreviousTurn;
|
||||
import com.superbiz.agent.harness.contract.PublishedResult;
|
||||
import com.superbiz.agent.harness.contract.ReleaseOutcome;
|
||||
import com.superbiz.agent.harness.core.RunBudgetUsage;
|
||||
import com.superbiz.agent.harness.core.RunContext;
|
||||
import com.superbiz.agent.harness.audit.ModelCallComponent;
|
||||
import com.superbiz.agent.repository.ChatSessionRepository;
|
||||
import com.superbiz.agent.repository.DiagnosisRunRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -32,19 +35,28 @@ public class JpaChatRunStore implements ChatRunStore {
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ObjectReader publishedReader;
|
||||
private final PublishedResultPolicy publishedPolicy;
|
||||
private final AgentStepAuditTracker stepTracker;
|
||||
|
||||
public JpaChatRunStore(ChatSessionRepository chatSessions,
|
||||
DiagnosisRunRepository runs,
|
||||
ObjectMapper objectMapper) {
|
||||
this(chatSessions, runs, objectMapper,
|
||||
new PublishedResultPolicy(PreviousTurnLimits.defaults()));
|
||||
new PublishedResultPolicy(PreviousTurnLimits.defaults()), null);
|
||||
}
|
||||
|
||||
public JpaChatRunStore(ChatSessionRepository chatSessions,
|
||||
DiagnosisRunRepository runs,
|
||||
ObjectMapper objectMapper,
|
||||
PublishedResultPolicy publishedPolicy) {
|
||||
this(chatSessions, runs, objectMapper, publishedPolicy, null);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public JpaChatRunStore(ChatSessionRepository chatSessions,
|
||||
DiagnosisRunRepository runs,
|
||||
ObjectMapper objectMapper,
|
||||
PublishedResultPolicy publishedPolicy) {
|
||||
PublishedResultPolicy publishedPolicy,
|
||||
@Nullable AgentStepAuditTracker stepTracker) {
|
||||
this.chatSessions = Objects.requireNonNull(chatSessions, "chatSessions must not be null");
|
||||
this.runs = Objects.requireNonNull(runs, "runs must not be null");
|
||||
this.objectMapper = Objects.requireNonNull(objectMapper, "objectMapper must not be null");
|
||||
@@ -52,6 +64,7 @@ public class JpaChatRunStore implements ChatRunStore {
|
||||
.with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
||||
.with(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
|
||||
this.publishedPolicy = Objects.requireNonNull(publishedPolicy, "publishedPolicy must not be null");
|
||||
this.stepTracker = stepTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,27 +123,34 @@ public class JpaChatRunStore implements ChatRunStore {
|
||||
String safeContentJson, PublishedResult publishedResult, int durationMs) {
|
||||
Objects.requireNonNull(context, "context must not be null");
|
||||
Objects.requireNonNull(outcome, "outcome must not be null");
|
||||
DiagnosisRun run = requiredRun(context.runId());
|
||||
run.setIntent(intent);
|
||||
run.setReleaseOutcome(outcome);
|
||||
run.setStatus(status(outcome));
|
||||
run.setAnswer(safeContentJson);
|
||||
run.setPublishedResult(outcome == ReleaseOutcome.SUCCESS && intent == IntentType.DIAGNOSIS
|
||||
&& publishedResult != null ? write(publishedResult) : null);
|
||||
run.setTotalDurationMs(Math.max(0, durationMs));
|
||||
RunBudgetUsage usage = context.budget().snapshot();
|
||||
run.setTotalTokenCount(saturatingInt(usage.totalTokens()));
|
||||
run.setStepCount(context.modelCalls().componentCallCount(
|
||||
ModelCallComponent.DIAGNOSIS_AGENT));
|
||||
run.setToolCallCount(saturatingInt(usage.toolCalls()));
|
||||
runs.save(run);
|
||||
if (outcome == ReleaseOutcome.SUCCESS || outcome == ReleaseOutcome.FALLBACK) {
|
||||
chatSessions.findBySessionId(context.sessionId()).ifPresent(session -> {
|
||||
session.setLastActiveAt(LocalDateTime.now());
|
||||
session.setMessagePairCount(
|
||||
session.getMessagePairCount() == null ? 1 : session.getMessagePairCount() + 1);
|
||||
chatSessions.save(session);
|
||||
});
|
||||
try {
|
||||
DiagnosisRun run = requiredRun(context.runId());
|
||||
run.setIntent(intent);
|
||||
run.setReleaseOutcome(outcome);
|
||||
run.setStatus(status(outcome));
|
||||
run.setAnswer(safeContentJson);
|
||||
run.setConclusion(RunConclusionExtractor.extract(objectMapper, safeContentJson));
|
||||
run.setPublishedResult(outcome == ReleaseOutcome.SUCCESS && intent == IntentType.DIAGNOSIS
|
||||
&& publishedResult != null ? write(publishedResult) : null);
|
||||
run.setTotalDurationMs(Math.max(0, durationMs));
|
||||
RunBudgetUsage usage = context.budget().snapshot();
|
||||
run.setTotalTokenCount(saturatingInt(usage.totalTokens()));
|
||||
run.setStepCount(context.modelCalls().componentCallCount(
|
||||
ModelCallComponent.DIAGNOSIS_AGENT));
|
||||
run.setToolCallCount(saturatingInt(usage.toolCalls()));
|
||||
runs.save(run);
|
||||
if (outcome == ReleaseOutcome.SUCCESS || outcome == ReleaseOutcome.FALLBACK) {
|
||||
chatSessions.findBySessionId(context.sessionId()).ifPresent(session -> {
|
||||
session.setLastActiveAt(LocalDateTime.now());
|
||||
session.setMessagePairCount(
|
||||
session.getMessagePairCount() == null ? 1 : session.getMessagePairCount() + 1);
|
||||
chatSessions.save(session);
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
if (stepTracker != null) {
|
||||
stepTracker.clear(context.runId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user