package ai import ( "encoding/json" "fmt" "net/http" ) // AgentEventType SSE / 回调事件类型。 const ( AgentEventStepStart = "step_start" AgentEventStep = "step" AgentEventDelta = "delta" AgentEventDone = "done" AgentEventError = "error" ) // AgentQueryResult 可供「在结果区打开」的行列结果。 type AgentQueryResult struct { Columns []string `json:"columns"` Rows []map[string]interface{} `json:"rows"` RowCount int `json:"rowCount"` SQL string `json:"sql,omitempty"` Tool string `json:"tool,omitempty"` } // AgentEvent 流式推送的一项。 type AgentEvent struct { Type string `json:"type"` Step *AgentStep `json:"step,omitempty"` Delta string `json:"delta,omitempty"` Content string `json:"content,omitempty"` SQL string `json:"sql,omitempty"` Steps []AgentStep `json:"steps,omitempty"` Rounds int `json:"rounds,omitempty"` Error string `json:"error,omitempty"` Result *AgentQueryResult `json:"result,omitempty"` } // AgentEmitter 可选;nil 时仅返回最终 AgentRes(非流式 fallback)。 type AgentEmitter func(AgentEvent) func emitEvent(emit AgentEmitter, ev AgentEvent) { if emit != nil { emit(ev) } } func chunkDelta(s string, size int) []string { if s == "" { return nil } if size <= 0 { size = 32 } r := []rune(s) var out []string for i := 0; i < len(r); i += size { j := i + size if j > len(r) { j = len(r) } out = append(out, string(r[i:j])) } return out } // WriteAgentSSE 写一条 SSE 事件并 Flush。 func WriteAgentSSE(w http.ResponseWriter, flusher http.Flusher, ev AgentEvent) error { b, err := json.Marshal(ev) if err != nil { return err } if _, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", ev.Type, b); err != nil { return err } flusher.Flush() return nil }