Merge pull request #1119 from trheyi/main
Implement hit and vote management enhancements in API
This commit is contained in:
commit
61a2765977
6 changed files with 391 additions and 117 deletions
|
|
@ -1,11 +1,12 @@
|
|||
package kb
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/graphrag/types"
|
||||
"github.com/yaoapp/yao/kb"
|
||||
"github.com/yaoapp/yao/openapi/response"
|
||||
)
|
||||
|
||||
|
|
@ -79,17 +80,47 @@ func ScrollHits(c *gin.Context) {
|
|||
options["filter"] = filter
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement scroll hits logic with GraphRag or database
|
||||
// TODO: Call kb.Instance.ScrollHits(c.Request.Context(), segmentID, options)
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Return mock response for now
|
||||
result := gin.H{
|
||||
"hits": []interface{}{},
|
||||
"scroll_id": nil,
|
||||
"has_more": false,
|
||||
"total": 0,
|
||||
"options": options,
|
||||
// Convert options to ScrollHitsOptions
|
||||
scrollOptions := &types.ScrollHitsOptions{
|
||||
SegmentID: segmentID,
|
||||
Limit: options["limit"].(int),
|
||||
}
|
||||
|
||||
// Set cursor if provided
|
||||
if scrollID, exists := options["scroll_id"]; exists && scrollID != nil {
|
||||
scrollOptions.Cursor = scrollID.(string)
|
||||
}
|
||||
|
||||
// Set filters if provided
|
||||
if filter, exists := options["filter"]; exists && filter != nil {
|
||||
filterMap := filter.(map[string]interface{})
|
||||
if source, ok := filterMap["source"]; ok {
|
||||
scrollOptions.Source = source.(string)
|
||||
}
|
||||
if scenario, ok := filterMap["scenario"]; ok {
|
||||
scrollOptions.Scenario = scenario.(string)
|
||||
}
|
||||
}
|
||||
|
||||
// Call GraphRag ScrollHits method
|
||||
result, err := kb.Instance.ScrollHits(c.Request.Context(), docID, scrollOptions)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to scroll hits: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
|
|
@ -131,34 +162,12 @@ func GetHits(c *gin.Context) {
|
|||
filter["session_id"] = sessionID
|
||||
}
|
||||
|
||||
// Parse limit parameter (optional, for basic limiting without pagination)
|
||||
var limit int
|
||||
if limitStr := c.Query("limit"); limitStr != "" {
|
||||
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 {
|
||||
limit = l
|
||||
}
|
||||
// TODO: Search functionality not implemented yet - reserved for future use
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Search hits functionality is reserved but not implemented yet",
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement get hits logic (simple query without pagination)
|
||||
// TODO: Call kb.Instance.GetHits(c.Request.Context(), segmentID, filter, limit)
|
||||
|
||||
// Return mock response for now
|
||||
result := gin.H{
|
||||
"hits": []interface{}{},
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"total": 0,
|
||||
}
|
||||
|
||||
if len(filter) > 0 {
|
||||
result["filter"] = filter
|
||||
}
|
||||
if limit > 0 {
|
||||
result["limit"] = limit
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
response.RespondWithError(c, response.StatusNotImplemented, errorResp)
|
||||
}
|
||||
|
||||
// GetHit gets a specific hit by ID
|
||||
|
|
@ -196,17 +205,44 @@ func GetHit(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement get hit detail logic
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"hit": nil,
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Call GraphRag GetHit method
|
||||
hit, err := kb.Instance.GetHit(c.Request.Context(), docID, segmentID, hitID)
|
||||
if err != nil {
|
||||
if err.Error() == "hit not found" {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "Hit not found",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusNotFound, errorResp)
|
||||
} else {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to get hit: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, gin.H{
|
||||
"hit": hit,
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"hit_id": hitID,
|
||||
})
|
||||
}
|
||||
|
||||
// AddHits adds new hits to a segment
|
||||
// AddHits adds new hits to a segment using UpdateHits implementation
|
||||
func AddHits(c *gin.Context) {
|
||||
// Extract docID from URL path
|
||||
docID := c.Param("docID")
|
||||
|
|
@ -230,14 +266,80 @@ func AddHits(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement add hit logic
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Hit added successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"hit_id": "placeholder-hit-id",
|
||||
})
|
||||
// Parse request body for hit data
|
||||
var req UpdateHitRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "Invalid request format: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if len(req.Segments) == 0 {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "At least one hit is required",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure all hits are for the correct segment
|
||||
for i := range req.Segments {
|
||||
req.Segments[i].ID = segmentID
|
||||
}
|
||||
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Build options with default reaction from payload or create basic fallback
|
||||
var options types.UpdateHitOptions
|
||||
if req.DefaultReaction != nil {
|
||||
// Use the default reaction provided in the request
|
||||
options.Reaction = req.DefaultReaction
|
||||
} else {
|
||||
// Create basic fallback context for segments that don't have reaction
|
||||
options.Reaction = &types.SegmentReaction{
|
||||
Source: "api",
|
||||
Scenario: "hit",
|
||||
Context: map[string]interface{}{
|
||||
"method": c.Request.Method,
|
||||
"path": c.Request.URL.Path,
|
||||
"client_ip": c.ClientIP(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Call GraphRag UpdateHits method
|
||||
updatedCount, err := kb.Instance.UpdateHits(c.Request.Context(), docID, req.Segments, options)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to add hits: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
result := gin.H{
|
||||
"message": "Hits added successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"hits": req.Segments,
|
||||
"updated_count": updatedCount,
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
}
|
||||
|
||||
// UpdateHits updates hits in batch
|
||||
|
|
@ -347,15 +449,42 @@ func RemoveHits(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement batch remove hit logic
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Build HitRemoval structs
|
||||
var hitRemovals []types.HitRemoval
|
||||
for _, hitID := range validHitIDs {
|
||||
hitRemovals = append(hitRemovals, types.HitRemoval{
|
||||
SegmentID: segmentID,
|
||||
HitID: hitID,
|
||||
})
|
||||
}
|
||||
|
||||
// Call GraphRag RemoveHits method
|
||||
removedCount, err := kb.Instance.RemoveHits(c.Request.Context(), docID, hitRemovals)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to remove hits: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
result := gin.H{
|
||||
"message": "Hits removed successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"hit_ids": validHitIDs,
|
||||
"removed_count": len(validHitIDs),
|
||||
"removed_count": removedCount,
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ func Attach(group *gin.RouterGroup, oauth types.OAuth) {
|
|||
group.GET("/documents/:docID/segments/:segmentID/votes/search", GetVotes)
|
||||
group.GET("/documents/:docID/segments/:segmentID/votes/:voteID", GetVote)
|
||||
group.POST("/documents/:docID/segments/:segmentID/votes", AddVotes)
|
||||
group.PUT("/documents/:docID/segments/:segmentID/votes", UpdateVotes)
|
||||
group.DELETE("/documents/:docID/segments/:segmentID/votes", RemoveVotes)
|
||||
|
||||
// Segment hits management
|
||||
|
|
@ -70,7 +69,6 @@ func Attach(group *gin.RouterGroup, oauth types.OAuth) {
|
|||
group.GET("/documents/:docID/segments/:segmentID/hits/search", GetHits)
|
||||
group.GET("/documents/:docID/segments/:segmentID/hits/:hitID", GetHit)
|
||||
group.POST("/documents/:docID/segments/:segmentID/hits", AddHits)
|
||||
group.PUT("/documents/:docID/segments/:segmentID/hits", UpdateHits)
|
||||
group.DELETE("/documents/:docID/segments/:segmentID/hits", RemoveHits)
|
||||
|
||||
// Search Management
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/yao/kb"
|
||||
"github.com/yaoapp/yao/openapi/response"
|
||||
)
|
||||
|
||||
|
|
@ -64,15 +65,22 @@ func UpdateScores(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement batch update scores logic
|
||||
// TODO: Call kb.Instance.UpdateScores(c.Request.Context(), docID, req.Scores)
|
||||
// Call GraphRag UpdateScores method (without Compute option)
|
||||
updatedCount, err := kb.Instance.UpdateScores(c.Request.Context(), docID, req.Scores)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to update scores: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
result := gin.H{
|
||||
"message": "Scores updated successfully",
|
||||
"doc_id": docID,
|
||||
"scores": req.Scores,
|
||||
"updated_count": len(req.Scores),
|
||||
"updated_count": updatedCount,
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
|
|
|
|||
|
|
@ -131,7 +131,14 @@ type UpdateSegmentsRequest struct {
|
|||
|
||||
// UpdateVoteRequest represents the request for UpdateVote API
|
||||
type UpdateVoteRequest struct {
|
||||
Segments []types.SegmentVote `json:"segments" binding:"required"`
|
||||
Segments []types.SegmentVote `json:"segments" binding:"required"`
|
||||
DefaultReaction *types.SegmentReaction `json:"default_reaction,omitempty"` // Optional default context for segments that don't have reaction
|
||||
}
|
||||
|
||||
// UpdateHitRequest represents the request for UpdateHit API
|
||||
type UpdateHitRequest struct {
|
||||
Segments []types.SegmentHit `json:"segments" binding:"required"`
|
||||
DefaultReaction *types.SegmentReaction `json:"default_reaction,omitempty"` // Optional default context for segments that don't have reaction
|
||||
}
|
||||
|
||||
// UpdateScoreRequest represents the request for UpdateScore API
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package kb
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/graphrag/types"
|
||||
"github.com/yaoapp/yao/kb"
|
||||
"github.com/yaoapp/yao/openapi/response"
|
||||
)
|
||||
|
||||
|
|
@ -76,17 +77,50 @@ func ScrollVotes(c *gin.Context) {
|
|||
options["filter"] = filter
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement scroll votes logic with GraphRag or database
|
||||
// TODO: Call kb.Instance.ScrollVotes(c.Request.Context(), segmentID, options)
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Return mock response for now
|
||||
result := gin.H{
|
||||
"votes": []interface{}{},
|
||||
"scroll_id": nil,
|
||||
"has_more": false,
|
||||
"total": 0,
|
||||
"options": options,
|
||||
// Convert options to ScrollVotesOptions
|
||||
scrollOptions := &types.ScrollVotesOptions{
|
||||
SegmentID: segmentID,
|
||||
Limit: options["limit"].(int),
|
||||
}
|
||||
|
||||
// Set cursor if provided
|
||||
if scrollID, exists := options["scroll_id"]; exists && scrollID != nil {
|
||||
scrollOptions.Cursor = scrollID.(string)
|
||||
}
|
||||
|
||||
// Set filters if provided
|
||||
if filter, exists := options["filter"]; exists && filter != nil {
|
||||
filterMap := filter.(map[string]interface{})
|
||||
if voteType, ok := filterMap["vote_type"]; ok {
|
||||
scrollOptions.VoteType = types.VoteType(voteType.(string))
|
||||
}
|
||||
if source, ok := filterMap["source"]; ok {
|
||||
scrollOptions.Source = source.(string)
|
||||
}
|
||||
if scenario, ok := filterMap["scenario"]; ok {
|
||||
scrollOptions.Scenario = scenario.(string)
|
||||
}
|
||||
}
|
||||
|
||||
// Call GraphRag ScrollVotes method
|
||||
result, err := kb.Instance.ScrollVotes(c.Request.Context(), docID, scrollOptions)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to scroll votes: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
|
|
@ -125,34 +159,12 @@ func GetVotes(c *gin.Context) {
|
|||
filter["user_id"] = userID
|
||||
}
|
||||
|
||||
// Parse limit parameter (optional, for basic limiting without pagination)
|
||||
var limit int
|
||||
if limitStr := c.Query("limit"); limitStr != "" {
|
||||
if l, err := strconv.Atoi(limitStr); err == nil && l > 0 {
|
||||
limit = l
|
||||
}
|
||||
// TODO: Search functionality not implemented yet - reserved for future use
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Search votes functionality is reserved but not implemented yet",
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement get votes logic (simple query without pagination)
|
||||
// TODO: Call kb.Instance.GetVotes(c.Request.Context(), segmentID, filter, limit)
|
||||
|
||||
// Return mock response for now
|
||||
result := gin.H{
|
||||
"votes": []interface{}{},
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"total": 0,
|
||||
}
|
||||
|
||||
if len(filter) > 0 {
|
||||
result["filter"] = filter
|
||||
}
|
||||
if limit > 0 {
|
||||
result["limit"] = limit
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
response.RespondWithError(c, response.StatusNotImplemented, errorResp)
|
||||
}
|
||||
|
||||
// GetVote gets a specific vote by ID
|
||||
|
|
@ -190,17 +202,44 @@ func GetVote(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement get vote detail logic
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"vote": nil,
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Call GraphRag GetVote method
|
||||
vote, err := kb.Instance.GetVote(c.Request.Context(), docID, segmentID, voteID)
|
||||
if err != nil {
|
||||
if err.Error() == "vote not found" {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "Vote not found",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusNotFound, errorResp)
|
||||
} else {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to get vote: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, gin.H{
|
||||
"vote": vote,
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"vote_id": voteID,
|
||||
})
|
||||
}
|
||||
|
||||
// AddVotes adds new votes to a segment
|
||||
// AddVotes adds new votes to a segment using UpdateVotes implementation
|
||||
func AddVotes(c *gin.Context) {
|
||||
// Extract docID from URL path
|
||||
docID := c.Param("docID")
|
||||
|
|
@ -224,14 +263,80 @@ func AddVotes(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement add vote logic
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Vote added successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"vote_id": "placeholder-vote-id",
|
||||
})
|
||||
// Parse request body for vote data
|
||||
var req UpdateVoteRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "Invalid request format: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if len(req.Segments) == 0 {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
ErrorDescription: "At least one vote is required",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusBadRequest, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure all votes are for the correct segment
|
||||
for i := range req.Segments {
|
||||
req.Segments[i].ID = segmentID
|
||||
}
|
||||
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Build options with default reaction from payload or create basic fallback
|
||||
var options types.UpdateVoteOptions
|
||||
if req.DefaultReaction != nil {
|
||||
// Use the default reaction provided in the request
|
||||
options.Reaction = req.DefaultReaction
|
||||
} else {
|
||||
// Create basic fallback context for segments that don't have reaction
|
||||
options.Reaction = &types.SegmentReaction{
|
||||
Source: "api",
|
||||
Scenario: "vote",
|
||||
Context: map[string]interface{}{
|
||||
"method": c.Request.Method,
|
||||
"path": c.Request.URL.Path,
|
||||
"client_ip": c.ClientIP(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Call GraphRag UpdateVotes method
|
||||
updatedCount, err := kb.Instance.UpdateVotes(c.Request.Context(), docID, req.Segments, options)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to add votes: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
result := gin.H{
|
||||
"message": "Votes added successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"votes": req.Segments,
|
||||
"updated_count": updatedCount,
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
}
|
||||
|
||||
// UpdateVotes updates votes in batch
|
||||
|
|
@ -341,15 +446,42 @@ func RemoveVotes(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO: Implement document permission validation for docID
|
||||
// TODO: Implement batch remove vote logic
|
||||
// Check if kb.Instance is available
|
||||
if kb.Instance == nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Knowledge base not initialized",
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
// Build VoteRemoval structs
|
||||
var voteRemovals []types.VoteRemoval
|
||||
for _, voteID := range validVoteIDs {
|
||||
voteRemovals = append(voteRemovals, types.VoteRemoval{
|
||||
SegmentID: segmentID,
|
||||
VoteID: voteID,
|
||||
})
|
||||
}
|
||||
|
||||
// Call GraphRag RemoveVotes method
|
||||
removedCount, err := kb.Instance.RemoveVotes(c.Request.Context(), docID, voteRemovals)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
ErrorDescription: "Failed to remove votes: " + err.Error(),
|
||||
}
|
||||
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
||||
return
|
||||
}
|
||||
|
||||
result := gin.H{
|
||||
"message": "Votes removed successfully",
|
||||
"doc_id": docID,
|
||||
"segment_id": segmentID,
|
||||
"vote_ids": validVoteIDs,
|
||||
"removed_count": len(validVoteIDs),
|
||||
"removed_count": removedCount,
|
||||
}
|
||||
|
||||
response.RespondWithSuccess(c, response.StatusOK, result)
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ func UpdateWeights(c *gin.Context) {
|
|||
|
||||
// TODO: Implement document permission validation for docID
|
||||
|
||||
// Perform batch update weight operation
|
||||
updatedCount, err := kb.Instance.UpdateWeight(c.Request.Context(), docID, req.Weights)
|
||||
// Call GraphRag UpdateWeights method (without Compute option)
|
||||
updatedCount, err := kb.Instance.UpdateWeights(c.Request.Context(), docID, req.Weights)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrServerError.Code,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue