MCPcopy Create free account
hub / github.com/astercloud/aster / handleStreamResponse

Method handleStreamResponse

pkg/agent/processor.go:873–1254  ·  view source on GitHub ↗

handleStreamResponse 处理流式响应(Phase 6C - 提取为独立方法以支持Middleware)

(ctx context.Context, stream <-chan provider.StreamChunk)

Source from the content-addressed store, hash-verified

871
872// handleStreamResponse 处理流式响应(Phase 6C - 提取为独立方法以支持Middleware)
873func (a *Agent) handleStreamResponse(ctx context.Context, stream <-chan provider.StreamChunk) (types.Message, error) {
874 assistantContent := make([]types.ContentBlock, 0)
875 currentBlockIndex := -1
876 textBuffers := make(map[int]string)
877 inputJSONBuffers := make(map[int]string)
878 reasoningStarted := false // 追踪是否已发送思考开始事件
879 var reasoningBuffer strings.Builder // 累积思考内容
880
881 // 只在用户消息后的第一次 LLM 调用时发送初始的任务规划思考事件
882 // 使用 initialThinkingSent 标志而不是 iterationCount,因为:
883 // 1. iterationCount 在 processMessages 中重置,但 handleStreamResponse 可能被多次调用
884 // 2. initialThinkingSent 确保每个用户消息只触发一次"任务规划"事件
885 a.mu.Lock()
886 shouldSendInitialThinking := !a.initialThinkingSent
887 if shouldSendInitialThinking {
888 a.initialThinkingSent = true // 标记已发送,防止重复
889 }
890 a.mu.Unlock()
891
892 if shouldSendInitialThinking {
893 // 发送初始的任务规划思考事件(所有模型通用)
894 // 这确保前端能显示"任务规划"思考框,即使模型不支持 reasoning_delta
895 a.eventBus.EmitProgress(&types.ProgressThinkChunkStartEvent{
896 Step: a.stepCount,
897 })
898 a.eventBus.EmitProgress(&types.ProgressThinkChunkEvent{
899 Step: a.stepCount,
900 Stage: types.ThinkingStageTaskPlanning,
901 Reasoning: "正在分析请求并规划执行策略...",
902 })
903 procLog.Debug(ctx, "sent initial task planning event", map[string]any{"step": a.stepCount})
904 }
905
906 for chunk := range stream {
907 // 调试:打印收到的每个 chunk
908 procLog.Debug(ctx, "received stream chunk", map[string]any{
909 "type": chunk.Type,
910 "index": chunk.Index,
911 "delta": fmt.Sprintf("%+v", chunk.Delta),
912 })
913
914 switch chunk.Type {
915 // 处理 reasoning_delta (DeepSeek Reasoner 模型的思考过程)
916 case "reasoning_delta":
917 if delta, ok := chunk.Delta.(map[string]any); ok {
918 if content, ok := delta["content"].(string); ok && content != "" {
919 // 首次收到思考内容时,发送开始事件
920 if !reasoningStarted {
921 reasoningStarted = true
922 a.eventBus.EmitProgress(&types.ProgressThinkChunkStartEvent{
923 Step: a.stepCount,
924 })
925 procLog.Debug(ctx, "reasoning started", map[string]any{"step": a.stepCount})
926 }
927 // 累积并发送思考内容增量
928 reasoningBuffer.WriteString(content)
929 a.eventBus.EmitProgress(&types.ProgressThinkChunkEvent{
930 Step: a.stepCount,

Callers 1

runModelStepMethod · 0.95

Calls 6

EmitProgressMethod · 0.80
EmitMonitorMethod · 0.80
DebugMethod · 0.65
InfoMethod · 0.65
WarnMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected