|
5 | 5 | "fmt" |
6 | 6 | "io" |
7 | 7 | "net/http" |
| 8 | + "net/url" |
8 | 9 | "os" |
9 | 10 | "path/filepath" |
10 | 11 | "strings" |
@@ -125,6 +126,7 @@ func registerAPIRoutes(e *echo.Echo, openAIClient *openai.Client, maxChunkingSiz |
125 | 126 | e.POST("/api/collections/:name/upload", uploadFile(collections, fileAssets)) |
126 | 127 | e.GET("/api/collections", listCollections) |
127 | 128 | e.GET("/api/collections/:name/entries", listFiles(collections)) |
| 129 | + e.GET("/api/collections/:name/entries/:entry", getEntryContent(collections)) |
128 | 130 | e.POST("/api/collections/:name/search", search(collections)) |
129 | 131 | e.POST("/api/collections/:name/reset", reset(collections)) |
130 | 132 | e.DELETE("/api/collections/:name/entry/delete", deleteEntryFromCollection(collections)) |
@@ -271,6 +273,51 @@ func listFiles(collections collectionList) func(c echo.Context) error { |
271 | 273 | } |
272 | 274 | } |
273 | 275 |
|
| 276 | +// getEntryContent returns the chunks (id, content, metadata) for a specific entry in a collection. |
| 277 | +func getEntryContent(collections collectionList) func(c echo.Context) error { |
| 278 | + return func(c echo.Context) error { |
| 279 | + name := c.Param("name") |
| 280 | + collection, exists := collections[name] |
| 281 | + if !exists { |
| 282 | + return c.JSON(http.StatusNotFound, errorResponse(ErrCodeNotFound, "Collection not found", fmt.Sprintf("Collection '%s' does not exist", name))) |
| 283 | + } |
| 284 | + |
| 285 | + entryParam := c.Param("entry") |
| 286 | + entry, err := url.PathUnescape(entryParam) |
| 287 | + if err != nil { |
| 288 | + entry = entryParam |
| 289 | + } |
| 290 | + |
| 291 | + results, err := collection.GetEntryContent(entry) |
| 292 | + if err != nil { |
| 293 | + if strings.Contains(err.Error(), "entry not found") { |
| 294 | + return c.JSON(http.StatusNotFound, errorResponse(ErrCodeNotFound, "Entry not found", fmt.Sprintf("Entry '%s' does not exist in collection '%s'", entry, name))) |
| 295 | + } |
| 296 | + if strings.Contains(err.Error(), "not implemented") { |
| 297 | + return c.JSON(http.StatusNotImplemented, errorResponse(ErrCodeInternalError, "Not supported", "This collection backend does not support listing entry content")) |
| 298 | + } |
| 299 | + return c.JSON(http.StatusInternalServerError, errorResponse(ErrCodeInternalError, "Failed to get entry content", err.Error())) |
| 300 | + } |
| 301 | + |
| 302 | + chunks := make([]map[string]interface{}, 0, len(results)) |
| 303 | + for _, r := range results { |
| 304 | + chunks = append(chunks, map[string]interface{}{ |
| 305 | + "id": r.ID, |
| 306 | + "content": r.Content, |
| 307 | + "metadata": r.Metadata, |
| 308 | + }) |
| 309 | + } |
| 310 | + |
| 311 | + response := successResponse("Entry content retrieved successfully", map[string]interface{}{ |
| 312 | + "collection": name, |
| 313 | + "entry": entry, |
| 314 | + "chunks": chunks, |
| 315 | + "count": len(chunks), |
| 316 | + }) |
| 317 | + return c.JSON(http.StatusOK, response) |
| 318 | + } |
| 319 | +} |
| 320 | + |
274 | 321 | // uploadFile handles uploading files to a collection |
275 | 322 | func uploadFile(collections collectionList, fileAssets string) func(c echo.Context) error { |
276 | 323 | return func(c echo.Context) error { |
|
0 commit comments