diff --git a/go.mod b/go.mod index 1f88639c8..5d8528ecb 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/slack-go/slack v0.17.3 github.com/stretchr/testify v1.11.1 github.com/tencent-connect/botgo v0.2.1 + github.com/yuin/goldmark v1.6.0 golang.org/x/oauth2 v0.35.0 ) diff --git a/go.sum b/go.sum index 0e95bf5cd..22743d3e4 100644 --- a/go.sum +++ b/go.sum @@ -149,6 +149,8 @@ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3i github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= +github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= diff --git a/pkg/channels/http.go b/pkg/channels/http.go index 044d1dc25..31313ff9d 100644 --- a/pkg/channels/http.go +++ b/pkg/channels/http.go @@ -7,10 +7,13 @@ import ( "fmt" "html/template" "net/http" + "strings" "sync" "time" "github.com/gorilla/websocket" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" "github.com/sipeed/picoclaw/pkg/bus" "github.com/sipeed/picoclaw/pkg/config" @@ -128,9 +131,12 @@ func (c *HTTPChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { return nil } + // Render Markdown to HTML before sending + renderedContent := renderMarkdown(msg.Content) + wsMsg := WSMessage{ Type: "response", - Content: msg.Content, + Content: renderedContent, ChatID: msg.ChatID, } @@ -272,4 +278,21 @@ func (c *HTTPChannel) removeSession(chatID string) { func generateChatID(r *http.Request) string { return fmt.Sprintf("web_%d", time.Now().UnixNano()) +} + +// renderMarkdown converts Markdown to HTML using goldmark +func renderMarkdown(input string) string { + md := goldmark.New( + goldmark.WithExtensions( + extension.GFM, + extension.TaskList, + extension.Typographer, + ), + ) + + var buf strings.Builder + if err := md.Convert([]byte(input), &buf); err != nil { + return input // fallback to plain text on error + } + return buf.String() } \ No newline at end of file diff --git a/pkg/channels/http_templates/index.html b/pkg/channels/http_templates/index.html index 224485d1d..62c425a67 100644 --- a/pkg/channels/http_templates/index.html +++ b/pkg/channels/http_templates/index.html @@ -247,13 +247,6 @@ function addMessage(content, type) { const div = document.createElement('div'); div.className = `message ${type}`; - - // Simple markdown-like formatting for code blocks - content = content.replace(/```(\w*)\n?([\s\S]*?)```/g, '
$2');
- content = content.replace(/`([^`]+)`/g, '$1');
- content = content.replace(/\*\*([^*]+)\*\*/g, '$1');
- content = content.replace(/\n/g, '