This commit is contained in:
lehel 2025-10-02 11:16:28 +02:00
parent f452c709c6
commit 509de38353
No known key found for this signature in database
GPG Key ID: 9C4F9D6111EE5CFA
6 changed files with 53 additions and 8 deletions

12
.gitignore vendored
View File

@ -1,2 +1,14 @@
reasons.bleve reasons.bleve
visits.bleve visits.bleve
# JetBrains / IntelliJ / GoLand project files
.idea/
*.iml
# Optional: uncomment if build output dir used by IDE
# out/
# More granular (kept for clarity; .idea/ above already covers these)
#.idea/**/workspace.xml
#.idea/**/tasks.xml
#.idea/**/shelf
#.idea/**/dataSources/
#.idea/**/libraries

View File

@ -13,5 +13,17 @@
</jdbc-additional-properties> </jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir> <working-dir>$ProjectFileDir$</working-dir>
</data-source> </data-source>
<data-source source="LOCAL" name="ragdb@vetrag.live" uuid="4464bfa3-4e16-44aa-b61e-e142cf841d2f">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://vetrag.live:5432/ragdb</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component> </component>
</project> </project>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DataSourcePerFileMappings"> <component name="DataSourcePerFileMappings">
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/4464bfa3-4e16-44aa-b61e-e142cf841d2f/console.sql" value="4464bfa3-4e16-44aa-b61e-e142cf841d2f" />
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/85be2c57-4234-463a-a995-092322f406a0/console.sql" value="85be2c57-4234-463a-a995-092322f406a0" /> <file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/85be2c57-4234-463a-a995-092322f406a0/console.sql" value="85be2c57-4234-463a-a995-092322f406a0" />
</component> </component>
</project> </project>

View File

@ -8,6 +8,7 @@ import (
"net/http/httptest" "net/http/httptest"
"sync" "sync"
"testing" "testing"
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -62,6 +63,17 @@ func (r *mapChatRepo) SaveLLMRawEvent(ctx context.Context, correlationID, phase,
r.rawEvents = append(r.rawEvents, struct{ CorrelationID, Phase, Raw string }{correlationID, phase, raw}) r.rawEvents = append(r.rawEvents, struct{ CorrelationID, Phase, Raw string }{correlationID, phase, raw})
return nil return nil
} }
func (r *mapChatRepo) ListLLMRawEvents(ctx context.Context, correlationID string, limit, offset int) ([]RawLLMEvent, error) {
r.mu.Lock()
defer r.mu.Unlock()
var out []RawLLMEvent
for _, e := range r.rawEvents {
if e.CorrelationID == correlationID {
out = append(out, RawLLMEvent{CorrelationID: e.CorrelationID, Phase: e.Phase, RawJSON: e.Raw, CreatedAt: time.Now()})
}
}
return out, nil
}
// testVisitDB2 replicates a minimal VisitDB for integration // testVisitDB2 replicates a minimal VisitDB for integration
// (avoids relying on real Bleve index) // (avoids relying on real Bleve index)

18
main.go
View File

@ -4,6 +4,7 @@ import (
"context" "context"
"os" "os"
"strconv" "strconv"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -97,17 +98,24 @@ func main() {
} }
c.JSON(200, gin.H{"items": items, "pagination": gin.H{"limit": limit, "offset": offset, "count": len(items)}}) c.JSON(200, gin.H{"items": items, "pagination": gin.H{"limit": limit, "offset": offset, "count": len(items)}})
}) })
// JSON: list raw LLM events for a correlation id // JSON: list raw LLM events for a correlation id OR serve UI when no correlation_id provided
r.GET("/admin/chats/events", func(c *gin.Context) { r.GET("/admin/chats/events", func(c *gin.Context) {
if repo == nil {
c.JSON(200, gin.H{"items": []RawLLMEvent{}, "pagination": gin.H{"limit": 0, "offset": 0, "count": 0}, "warning": "repository not configured"})
return
}
corr := c.Query("correlation_id") corr := c.Query("correlation_id")
if corr == "" { if corr == "" {
if strings.Contains(c.GetHeader("Accept"), "application/json") {
c.JSON(400, gin.H{"error": "missing correlation_id"}) c.JSON(400, gin.H{"error": "missing correlation_id"})
return return
} }
c.Status(200)
if err := uiAdminChatsTemplate.Execute(c.Writer, nil); err != nil {
logrus.Errorf("Failed to execute ui_admin_chats.html template: %v", err)
}
return
}
if repo == nil { // repository not configured, return empty JSON set for events
c.JSON(200, gin.H{"items": []RawLLMEvent{}, "pagination": gin.H{"limit": 0, "offset": 0, "count": 0}, "warning": "repository not configured"})
return
}
limit := 100 limit := 100
if ls := c.Query("limit"); ls != "" { if ls := c.Query("limit"); ls != "" {
if v, err := strconv.Atoi(ls); err == nil { if v, err := strconv.Atoi(ls); err == nil {

View File

@ -42,7 +42,7 @@ func TestLLMClient_OpenRouterStyle_ExtractKeywords(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
llm := NewLLMClient("test-key", ts.URL+"/v1/chat/completions", "meta-llama/test") llm := NewLLMClient("test-key", ts.URL+"/v1/chat/completions", "meta-llama/test", nil)
res, err := llm.ExtractKeywords(context.Background(), "kutya hasmenés") res, err := llm.ExtractKeywords(context.Background(), "kutya hasmenés")
if err != nil { if err != nil {
te(t, "unexpected error: %v", err) te(t, "unexpected error: %v", err)
@ -77,7 +77,7 @@ func TestLLMClient_OpenRouterStyle_Error(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
llm := NewLLMClient("test-key", ts.URL+"/v1/chat/completions", "meta-llama/test") llm := NewLLMClient("test-key", ts.URL+"/v1/chat/completions", "meta-llama/test", nil)
_, err := llm.ExtractKeywords(context.Background(), "test") _, err := llm.ExtractKeywords(context.Background(), "test")
if err == nil || !contains(err.Error(), "Rate limit") { if err == nil || !contains(err.Error(), "Rate limit") {
te(t, "expected rate limit error, got: %v", err) te(t, "expected rate limit error, got: %v", err)