diff --git a/kb/config.go b/kb/config.go new file mode 100644 index 00000000..edfaf336 --- /dev/null +++ b/kb/config.go @@ -0,0 +1,3 @@ +package kb + +// Config parses the Knowledge Base configuration diff --git a/kb/kb.go b/kb/kb.go new file mode 100644 index 00000000..8abceb50 --- /dev/null +++ b/kb/kb.go @@ -0,0 +1,11 @@ +package kb + +import "github.com/yaoapp/gou/graphrag/types" + +// Instance is the GraphRag instance +var Instance types.GraphRag = nil + +// Load loads the GraphRag instance +func Load(config *Config) error { + return nil +} diff --git a/kb/types.go b/kb/types.go new file mode 100644 index 00000000..4ab22421 --- /dev/null +++ b/kb/types.go @@ -0,0 +1,4 @@ +package kb + +// Config is the configuration for the Knowledge Base +type Config struct{} diff --git a/openapi/kb/backup.go b/openapi/kb/backup.go new file mode 100644 index 00000000..6093c78a --- /dev/null +++ b/openapi/kb/backup.go @@ -0,0 +1,23 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Collection Backup and Restore Handlers + +// Backup backs up a collection +func Backup(c *gin.Context) { + // TODO: Implement backup logic + c.Header("Content-Type", "application/octet-stream") + c.Header("Content-Disposition", "attachment; filename=collection-backup.gz") + c.Status(http.StatusOK) +} + +// Restore restores a collection +func Restore(c *gin.Context) { + // TODO: Implement restore logic + c.JSON(http.StatusOK, gin.H{"message": "Collection restored"}) +} diff --git a/openapi/kb/collection.go b/openapi/kb/collection.go new file mode 100644 index 00000000..e6364114 --- /dev/null +++ b/openapi/kb/collection.go @@ -0,0 +1,38 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/yaoapp/yao/kb" +) + +// Collection Management Handlers + +// CreateCollection creates a new collection +func CreateCollection(c *gin.Context) { + // TODO: Implement create collection logic + c.JSON(http.StatusCreated, gin.H{"message": "Collection created"}) +} + +// RemoveCollection removes an existing collection +func RemoveCollection(c *gin.Context) { + // TODO: Implement remove collection logic + c.JSON(http.StatusOK, gin.H{"message": "Collection removed"}) +} + +// CollectionExists checks if a collection exists +func CollectionExists(c *gin.Context) { + // TODO: Implement collection exists check logic + c.JSON(http.StatusOK, gin.H{"exists": false}) +} + +// GetCollections retrieves collections with optional filtering +func GetCollections(c *gin.Context) { + collections, err := kb.Instance.GetCollections(c.Request.Context(), map[string]interface{}{}) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, collections) +} diff --git a/openapi/kb/document.go b/openapi/kb/document.go new file mode 100644 index 00000000..565e2496 --- /dev/null +++ b/openapi/kb/document.go @@ -0,0 +1,76 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Document Management Handlers + +// AddFile adds a file to a collection +func AddFile(c *gin.Context) { + // TODO: Implement add file logic + c.JSON(http.StatusCreated, gin.H{"message": "File added"}) +} + +// AddText adds text to a collection +func AddText(c *gin.Context) { + // TODO: Implement add text logic + c.JSON(http.StatusCreated, gin.H{"message": "Text added"}) +} + +// AddURL adds a URL to a collection +func AddURL(c *gin.Context) { + // TODO: Implement add URL logic + c.JSON(http.StatusCreated, gin.H{"message": "URL added"}) +} + +// ListDocuments lists documents with pagination +func ListDocuments(c *gin.Context) { + // TODO: Implement list documents logic + // Query parameters for pagination: page, limit, filter, etc. + c.JSON(http.StatusOK, gin.H{ + "documents": []interface{}{}, + "total": 0, + "page": 1, + "limit": 20, + }) +} + +// ScrollDocuments scrolls through documents with iterator-style pagination +func ScrollDocuments(c *gin.Context) { + // TODO: Implement scroll documents logic + // Query parameters: cursor, limit, filter, etc. + c.JSON(http.StatusOK, gin.H{ + "documents": []interface{}{}, + "cursor": "", + "hasMore": false, + }) +} + +// GetDocument gets document details by document ID +func GetDocument(c *gin.Context) { + // TODO: Implement get document logic + // Note: This might need to be implemented based on your document storage structure + // as the GraphRag interface doesn't directly provide a GetDocument method + docID := c.Param("docID") + if docID == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "Document ID is required"}) + return + } + + // TODO: Implement actual document retrieval logic + // This could involve querying your document storage or getting document metadata + c.JSON(http.StatusOK, gin.H{ + "docID": docID, + "message": "Document details retrieved", + // Add actual document fields here when implementing + }) +} + +// RemoveDocs removes documents by IDs +func RemoveDocs(c *gin.Context) { + // TODO: Implement remove documents logic + c.JSON(http.StatusOK, gin.H{"message": "Documents removed"}) +} diff --git a/openapi/kb/kb.go b/openapi/kb/kb.go index b310b909..e216cf2e 100644 --- a/openapi/kb/kb.go +++ b/openapi/kb/kb.go @@ -1 +1,59 @@ package kb + +import ( + "github.com/gin-gonic/gin" + "github.com/yaoapp/kun/log" + "github.com/yaoapp/yao/kb" + "github.com/yaoapp/yao/openapi/oauth/types" +) + +// Attach attaches the Knowledge Base API to the router +func Attach(group *gin.RouterGroup, oauth types.OAuth) { + + // Validate the GraphRag instance + if kb.Instance == nil { + log.Warn("[OpenAPI] GraphRag instance is not set, please check the configuration") + return + } + + // Protect all endpoints with OAuth + group.Use(oauth.Guard) + + // Collection Management + group.POST("/collections", CreateCollection) + group.DELETE("/collections/:collectionID", RemoveCollection) + group.GET("/collections/:collectionID/exists", CollectionExists) + group.GET("/collections", GetCollections) + + // Document Management + group.POST("/collections/:collectionID/documents/file", AddFile) + group.POST("/collections/:collectionID/documents/text", AddText) + group.POST("/collections/:collectionID/documents/url", AddURL) + group.GET("/documents", ListDocuments) + group.GET("/documents/scroll", ScrollDocuments) + group.GET("/documents/:docID", GetDocument) + group.DELETE("/documents", RemoveDocs) + + // Segment Management + group.POST("/documents/:docID/segments", AddSegments) + group.PUT("/segments", UpdateSegments) + group.DELETE("/segments", RemoveSegments) + group.DELETE("/documents/:docID/segments", RemoveSegmentsByDocID) + group.GET("/segments", GetSegments) + group.GET("/segments/:segmentID", GetSegment) + group.GET("/documents/:docID/segments", ListSegments) + group.GET("/documents/:docID/segments/scroll", ScrollSegments) + + // Segment Voting, Scoring, Weighting + group.PUT("/segments/vote", UpdateVote) + group.PUT("/segments/score", UpdateScore) + group.PUT("/segments/weight", UpdateWeight) + + // Search Management + group.POST("/search", Search) + group.POST("/search/multi", MultiSearch) + + // Collection Backup and Restore + group.POST("/collections/:collectionID/backup", Backup) + group.POST("/collections/:collectionID/restore", Restore) +} diff --git a/openapi/kb/search.go b/openapi/kb/search.go new file mode 100644 index 00000000..c5618612 --- /dev/null +++ b/openapi/kb/search.go @@ -0,0 +1,21 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Search Management Handlers + +// Search searches for segments +func Search(c *gin.Context) { + // TODO: Implement search logic + c.JSON(http.StatusOK, gin.H{"results": []interface{}{}}) +} + +// MultiSearch performs multi-search for segments +func MultiSearch(c *gin.Context) { + // TODO: Implement multi-search logic + c.JSON(http.StatusOK, gin.H{"results": map[string]interface{}{}}) +} diff --git a/openapi/kb/segment.go b/openapi/kb/segment.go new file mode 100644 index 00000000..9eb55289 --- /dev/null +++ b/openapi/kb/segment.go @@ -0,0 +1,57 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Segment Management Handlers + +// AddSegments adds segments to a document +func AddSegments(c *gin.Context) { + // TODO: Implement add segments logic + c.JSON(http.StatusCreated, gin.H{"message": "Segments added"}) +} + +// UpdateSegments updates segments manually +func UpdateSegments(c *gin.Context) { + // TODO: Implement update segments logic + c.JSON(http.StatusOK, gin.H{"message": "Segments updated"}) +} + +// RemoveSegments removes segments by IDs +func RemoveSegments(c *gin.Context) { + // TODO: Implement remove segments logic + c.JSON(http.StatusOK, gin.H{"message": "Segments removed"}) +} + +// RemoveSegmentsByDocID removes all segments of a document +func RemoveSegmentsByDocID(c *gin.Context) { + // TODO: Implement remove segments by document ID logic + c.JSON(http.StatusOK, gin.H{"message": "Segments removed by document ID"}) +} + +// GetSegments gets segments by IDs +func GetSegments(c *gin.Context) { + // TODO: Implement get segments logic + c.JSON(http.StatusOK, gin.H{"segments": []interface{}{}}) +} + +// GetSegment gets a single segment by ID +func GetSegment(c *gin.Context) { + // TODO: Implement get single segment logic + c.JSON(http.StatusOK, gin.H{"segment": nil}) +} + +// ListSegments lists segments with pagination +func ListSegments(c *gin.Context) { + // TODO: Implement list segments with pagination logic + c.JSON(http.StatusOK, gin.H{"segments": []interface{}{}, "total": 0, "page": 1}) +} + +// ScrollSegments scrolls segments with iterator-style pagination +func ScrollSegments(c *gin.Context) { + // TODO: Implement scroll segments logic + c.JSON(http.StatusOK, gin.H{"segments": []interface{}{}, "cursor": ""}) +} diff --git a/openapi/kb/vote.go b/openapi/kb/vote.go new file mode 100644 index 00000000..6dbd828d --- /dev/null +++ b/openapi/kb/vote.go @@ -0,0 +1,27 @@ +package kb + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Segment Voting, Scoring, Weighting Handlers + +// UpdateVote updates votes for segments +func UpdateVote(c *gin.Context) { + // TODO: Implement update vote logic + c.JSON(http.StatusOK, gin.H{"message": "Vote updated"}) +} + +// UpdateScore updates scores for segments +func UpdateScore(c *gin.Context) { + // TODO: Implement update score logic + c.JSON(http.StatusOK, gin.H{"message": "Score updated"}) +} + +// UpdateWeight updates weights for segments +func UpdateWeight(c *gin.Context) { + // TODO: Implement update weight logic + c.JSON(http.StatusOK, gin.H{"message": "Weight updated"}) +} diff --git a/openapi/openapi.go b/openapi/openapi.go index e867fd0d..05768d7f 100644 --- a/openapi/openapi.go +++ b/openapi/openapi.go @@ -8,6 +8,7 @@ import ( "github.com/yaoapp/yao/config" "github.com/yaoapp/yao/openapi/dsl" "github.com/yaoapp/yao/openapi/hello" + "github.com/yaoapp/yao/openapi/kb" "github.com/yaoapp/yao/openapi/oauth" "github.com/yaoapp/yao/openapi/oauth/types" ) @@ -78,5 +79,8 @@ func (openapi *OpenAPI) Attach(router *gin.Engine) { // DSL handlers dsl.Attach(group.Group("/dsl"), openapi.OAuth) + // Knowledge Base handlers + kb.Attach(group.Group("/kb"), openapi.OAuth) + // Custom handlers (Defined by developer) }