Fix truncation issues in piplan, SQLite storage, and history compression; add PIPlanMaxChars configuration
This commit is contained in:
@@ -15,6 +15,8 @@ import (
|
||||
"laodingbot/internal/config"
|
||||
"laodingbot/internal/llm"
|
||||
"laodingbot/internal/logger"
|
||||
"laodingbot/internal/memory"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type IncomingMessage struct {
|
||||
@@ -32,20 +34,26 @@ const (
|
||||
StreamEventTypeToolResult StreamEventType = "tool_result" // 工具执行结果
|
||||
StreamEventTypeFinal StreamEventType = "final" // 最终答案
|
||||
StreamEventTypeError StreamEventType = "error" // 错误信息
|
||||
|
||||
StreamEventTypeWorkspaceStart StreamEventType = "workspace_start" // 工具渲染开始
|
||||
StreamEventTypeWorkspaceDelta StreamEventType = "workspace_delta" // 工具渲染增量内容
|
||||
StreamEventTypeWorkspaceEnd StreamEventType = "workspace_end" // 工具渲染结束
|
||||
)
|
||||
|
||||
// StreamEvent 代表流式输出中的一个事件
|
||||
type StreamEvent struct {
|
||||
Type StreamEventType `json:"type"`
|
||||
Content string `json:"content"`
|
||||
Step int `json:"step,omitempty"`
|
||||
ToolName string `json:"tool_name,omitempty"`
|
||||
Type StreamEventType `json:"type"`
|
||||
Content string `json:"content"`
|
||||
Step int `json:"step,omitempty"`
|
||||
ToolName string `json:"tool_name,omitempty"`
|
||||
WorkspaceTitle string `json:"workspace_title,omitempty"` // 仅用于 workspace_start 类型
|
||||
}
|
||||
|
||||
type ChatHandler func(context.Context, IncomingMessage) (string, error)
|
||||
type StreamChatHandler func(context.Context, IncomingMessage, StreamEventCallback) (string, error)
|
||||
type StreamEventCallback func(event StreamEvent) error
|
||||
type UploadHandler func(context.Context, string, string, []llm.InputFile) ([]string, error)
|
||||
type HistoryHandler func(context.Context, string, int) ([]memory.Message, error)
|
||||
|
||||
type Bot struct {
|
||||
listenAddr string
|
||||
@@ -55,6 +63,7 @@ type Bot struct {
|
||||
chatHandler ChatHandler
|
||||
streamChatHandler StreamChatHandler
|
||||
uploadHandler UploadHandler
|
||||
historyHandler HistoryHandler
|
||||
counter uint64
|
||||
}
|
||||
|
||||
@@ -118,7 +127,7 @@ func NewBot(cfg config.WebUIConfig, log *logger.Logger) (*Bot, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *Bot) Run(ctx context.Context, chatHandler ChatHandler, streamChatHandler StreamChatHandler, uploadHandler UploadHandler) error {
|
||||
func (b *Bot) Run(ctx context.Context, chatHandler ChatHandler, streamChatHandler StreamChatHandler, uploadHandler UploadHandler, historyHandler HistoryHandler) error {
|
||||
if chatHandler == nil {
|
||||
return fmt.Errorf("nil webui chat handler")
|
||||
}
|
||||
@@ -128,11 +137,13 @@ func (b *Bot) Run(ctx context.Context, chatHandler ChatHandler, streamChatHandle
|
||||
b.chatHandler = chatHandler
|
||||
b.streamChatHandler = streamChatHandler
|
||||
b.uploadHandler = uploadHandler
|
||||
b.historyHandler = historyHandler
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/chat", b.handleChat)
|
||||
mux.HandleFunc("/api/chat/stream", b.handleChatStream)
|
||||
mux.HandleFunc("/api/upload", b.handleUpload)
|
||||
mux.HandleFunc("/api/history", b.handleHistory)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: b.listenAddr,
|
||||
@@ -220,6 +231,42 @@ func (b *Bot) handleChat(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Bot) handleHistory(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writeJSON(w, http.StatusMethodNotAllowed, errorResponse{Error: "method not allowed"})
|
||||
return
|
||||
}
|
||||
if b.historyHandler == nil {
|
||||
writeJSON(w, http.StatusInternalServerError, errorResponse{Error: "history handler not ready"})
|
||||
return
|
||||
}
|
||||
|
||||
sessionID := strings.TrimSpace(r.URL.Query().Get("session_id"))
|
||||
if sessionID == "" {
|
||||
writeJSON(w, http.StatusBadRequest, errorResponse{Error: "session_id is required"})
|
||||
return
|
||||
}
|
||||
|
||||
limitStr := strings.TrimSpace(r.URL.Query().Get("limit"))
|
||||
limit := 20
|
||||
if limitStr != "" {
|
||||
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 {
|
||||
limit = l
|
||||
}
|
||||
}
|
||||
|
||||
history, err := b.historyHandler(r.Context(), sessionID, limit)
|
||||
if err != nil {
|
||||
if b.log != nil {
|
||||
b.log.Errorf("webui history handler failed session_id=%s err=%v", sessionID, err)
|
||||
}
|
||||
writeJSON(w, http.StatusInternalServerError, errorResponse{Error: "load history failed"})
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, history)
|
||||
}
|
||||
|
||||
func firstNonEmpty(vals ...string) string {
|
||||
|
||||
for _, v := range vals {
|
||||
|
||||
Reference in New Issue
Block a user