zhou zhou
昨天 b05f094ac51dce91eb8c00235226d54a04658c6d
rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatOrchestrator.java
@@ -57,6 +57,7 @@
        String requestId = request.getRequestId();
        long startedAt = System.currentTimeMillis();
        AtomicReference<Long> firstTokenAtRef = new AtomicReference<>();
        AtomicLong traceSequence = new AtomicLong(0);
        AtomicLong toolCallSequence = new AtomicLong(0);
        AtomicLong toolSuccessCount = new AtomicLong(0);
        AtomicLong toolFailureCount = new AtomicLong(0);
@@ -64,7 +65,7 @@
        Long callLogId = null;
        String model = null;
        String resolvedPromptCode = request.getPromptCode();
        AiThinkingTraceEmitter thinkingTraceEmitter = null;
        AiChatTraceEmitter traceEmitter = null;
        try {
            ensureIdentity(userId, tenantId);
            AiResolvedConfig config = resolveConfig(request, tenantId);
@@ -115,13 +116,13 @@
                        .build());
                log.info("AI chat started, requestId={}, userId={}, tenantId={}, sessionId={}, model={}",
                        requestId, userId, tenantId, session.getId(), resolvedModel);
                thinkingTraceEmitter = new AiThinkingTraceEmitter(aiSseEventPublisher, emitter, requestId, session.getId());
                thinkingTraceEmitter.startAnalyze();
                AiThinkingTraceEmitter activeThinkingTraceEmitter = thinkingTraceEmitter;
                traceEmitter = new AiChatTraceEmitter(aiSseEventPublisher, emitter, requestId, session.getId(), traceSequence);
                traceEmitter.startAnalyze();
                AiChatTraceEmitter activeTraceEmitter = traceEmitter;
                ToolCallback[] observableToolCallbacks = aiToolObservationService.wrapToolCallbacks(
                        runtime.getToolCallbacks(), emitter, requestId, session.getId(), toolCallSequence,
                        toolSuccessCount, toolFailureCount, callLogId, userId, tenantId, activeThinkingTraceEmitter
                        runtime.getToolCallbacks(), requestId, session.getId(), toolCallSequence,
                        toolSuccessCount, toolFailureCount, callLogId, userId, tenantId, activeTraceEmitter
                );
                Prompt prompt = new Prompt(
                        aiPromptMessageBuilder.buildPromptMessages(memory, mergedMessages, config.getPrompt(), request.getMetadata()),
@@ -134,10 +135,10 @@
                    String content = extractContent(response);
                    aiChatMemoryService.saveRound(session, userId, tenantId, request.getMessages(), content);
                    if (StringUtils.hasText(content)) {
                        aiSseEventPublisher.markFirstToken(firstTokenAtRef, emitter, requestId, session.getId(), resolvedModel, startedAt, activeThinkingTraceEmitter);
                        aiSseEventPublisher.markFirstToken(firstTokenAtRef, emitter, requestId, session.getId(), resolvedModel, startedAt, activeTraceEmitter);
                        aiSseEventPublisher.emitStrict(emitter, "delta", aiSseEventPublisher.buildMessagePayload("requestId", requestId, "content", content));
                    }
                    activeThinkingTraceEmitter.completeCurrentPhase();
                    activeTraceEmitter.completeCurrentPhase();
                    aiSseEventPublisher.emitDone(emitter, requestId, response.getMetadata(), config.getAiParam().getModel(),
                            session.getId(), startedAt, firstTokenAtRef.get());
                    aiSseEventPublisher.emitSafely(emitter, "status",
@@ -169,7 +170,7 @@
                                lastMetadata.set(response.getMetadata());
                                String content = extractContent(response);
                                if (StringUtils.hasText(content)) {
                                    aiSseEventPublisher.markFirstToken(firstTokenAtRef, emitter, requestId, session.getId(), resolvedModel, startedAt, activeThinkingTraceEmitter);
                                    aiSseEventPublisher.markFirstToken(firstTokenAtRef, emitter, requestId, session.getId(), resolvedModel, startedAt, activeTraceEmitter);
                                    assistantContent.append(content);
                                    aiSseEventPublisher.emitStrict(emitter, "delta",
                                            aiSseEventPublisher.buildMessagePayload("requestId", requestId, "content", content));
@@ -181,7 +182,7 @@
                            e == null ? "AI 模型流式调用失败" : e.getMessage(), e);
                }
                aiChatMemoryService.saveRound(session, userId, tenantId, request.getMessages(), assistantContent.toString());
                activeThinkingTraceEmitter.completeCurrentPhase();
                activeTraceEmitter.completeCurrentPhase();
                aiSseEventPublisher.emitDone(emitter, requestId, lastMetadata.get(), config.getAiParam().getModel(),
                        session.getId(), startedAt, firstTokenAtRef.get());
                aiSseEventPublisher.emitSafely(emitter, "status",
@@ -205,13 +206,13 @@
            }
        } catch (AiChatException e) {
            aiChatFailureHandler.handleStreamFailure(emitter, requestId, sessionId, model, startedAt, firstTokenAtRef.get(), e,
                    callLogId, toolSuccessCount.get(), toolFailureCount.get(), thinkingTraceEmitter,
                    callLogId, toolSuccessCount.get(), toolFailureCount.get(), traceEmitter,
                    tenantId, userId, resolvedPromptCode);
        } catch (Exception e) {
            aiChatFailureHandler.handleStreamFailure(emitter, requestId, sessionId, model, startedAt, firstTokenAtRef.get(),
                    aiChatFailureHandler.buildAiException("AI_INTERNAL_ERROR", AiErrorCategory.INTERNAL, "INTERNAL",
                            e == null ? "AI 对话失败" : e.getMessage(), e),
                    callLogId, toolSuccessCount.get(), toolFailureCount.get(), thinkingTraceEmitter,
                    callLogId, toolSuccessCount.get(), toolFailureCount.get(), traceEmitter,
                    tenantId, userId, resolvedPromptCode);
        } finally {
            log.debug("AI chat stream finished, requestId={}", requestId);