diff --git a/api/apps/restful_apis/agent_api.py b/api/apps/restful_apis/agent_api.py index 6477ff8964..8d825a4a19 100644 --- a/api/apps/restful_apis/agent_api.py +++ b/api/apps/restful_apis/agent_api.py @@ -2572,7 +2572,7 @@ async def _stream_agent_attachment(tenant_id, attachment_id, *, inline: bool): content_type, ext, filename = _attachment_request_metadata() data = await thread_pool_exec(settings.STORAGE_IMPL.get, tenant_id, attachment_id) if not data: - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") response = await make_response(data) if inline: apply_preview_file_response_headers(response, content_type, ext, filename) diff --git a/api/apps/restful_apis/chunk_api.py b/api/apps/restful_apis/chunk_api.py index e5a78cdf96..8ce7319fbc 100644 --- a/api/apps/restful_apis/chunk_api.py +++ b/api/apps/restful_apis/chunk_api.py @@ -1199,9 +1199,9 @@ async def switch_chunks(tenant_id, dataset_id, document_id): def _switch_sync(): e, doc = DocumentService.get_by_id(document_id) if not e: - return get_error_data_result(message="Document not found!") + return get_error_data_result(message="document not found") if not doc or str(doc.kb_id) != str(dataset_id): - return get_error_data_result(message="Document not found!") + return get_error_data_result(message="document not found") for cid in req["chunk_ids"]: if not settings.docStoreConn.update( {"id": cid}, diff --git a/api/apps/restful_apis/document_api.py b/api/apps/restful_apis/document_api.py index 71d1b48185..cb1a575de7 100644 --- a/api/apps/restful_apis/document_api.py +++ b/api/apps/restful_apis/document_api.py @@ -1253,7 +1253,7 @@ async def update_metadata_config(tenant_id, dataset_id, document_id): try: e, doc = DocumentService.get_by_id(doc.id) if not e: - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") except Exception as e: return get_json_result(code=RetCode.EXCEPTION_ERROR, message=repr(e)) @@ -1462,7 +1462,7 @@ def _run_sync(user_id: str, req): return RetCode.DATA_ERROR, "Tenant not found!" e, doc = DocumentService.get_by_id(doc_id) if not e: - return RetCode.DATA_ERROR, "Document not found!" + return RetCode.DATA_ERROR, "document not found" if str(req["run"]) == TaskStatus.CANCEL.value: tasks = list(TaskService.query(doc_id=doc_id)) @@ -1904,7 +1904,7 @@ async def get_artifact(filename): return get_data_error_result(message="Invalid filename.") ext = os.path.splitext(basename)[1].lower() if ext not in ARTIFACT_CONTENT_TYPES: - return get_data_error_result(message="Invalid file type.") + return get_data_error_result(message="invalid file type") session_id = request.args.get("session_id", "") if not await thread_pool_exec(_sandbox_artifact_accessible, basename, current_user.id) and not await thread_pool_exec(_sandbox_artifact_session_accessible, session_id, current_user.id): return get_data_error_result(message="Artifact not found.") @@ -2054,11 +2054,11 @@ async def get(doc_id): """ try: if not DocumentService.accessible(doc_id, current_user.id): - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") e, doc = DocumentService.get_by_id(doc_id) if not e: - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") b, n = File2DocumentService.get_storage_address(doc_id=doc_id) data = await thread_pool_exec(settings.STORAGE_IMPL.get, b, n) @@ -2128,9 +2128,9 @@ async def download(dataset_id, document_id): if not document_id: return get_error_data_result(message="Specify document_id please.") if not KnowledgebaseService.accessible(kb_id=dataset_id, user_id=current_user.id): - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") if not DocumentService.accessible(document_id, current_user.id): - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") doc = DocumentService.query(kb_id=dataset_id, id=document_id) if not doc: return get_error_data_result(message=f"The dataset not own the document {document_id}.") @@ -2190,7 +2190,7 @@ async def download_document(document_id): if not document_id: return get_error_data_result(message="Specify document_id please.") if not DocumentService.accessible(document_id, current_user.id): - return get_data_error_result(message="Document not found!") + return get_data_error_result(message="document not found") doc = DocumentService.query(id=document_id) if not doc: return get_error_data_result(message=f"The dataset not own the document {document_id}.") diff --git a/api/apps/services/document_api_service.py b/api/apps/services/document_api_service.py index 6292f92044..d6ca3e5623 100644 --- a/api/apps/services/document_api_service.py +++ b/api/apps/services/document_api_service.py @@ -126,7 +126,7 @@ def reset_document_for_reparse(doc, tenant_id, parser_id=None, pipeline_id=None) # Update document e = DocumentService.update_by_id(doc.id, update_fields) if not e: - return get_error_data_result(message="Document not found!") + return get_error_data_result(message="document not found") # Update document statistics before deleting all document rows. Pipeline # compilation rows may exist even when token_num is zero, so the doc-store @@ -141,9 +141,9 @@ def reset_document_for_reparse(doc, tenant_id, parser_id=None, pipeline_id=None) doc.process_duration * -1, ) except LookupError: - return get_error_data_result(message="Document not found!") + return get_error_data_result(message="document not found") if not e: - return get_error_data_result(message="Document not found!") + return get_error_data_result(message="document not found") settings.docStoreConn.delete({"doc_id": doc.id}, search.index_name(tenant_id), doc.kb_id) # Delete chunk images diff --git a/api/apps/services/file_api_service.py b/api/apps/services/file_api_service.py index f0d870ffac..966ee61a9f 100644 --- a/api/apps/services/file_api_service.py +++ b/api/apps/services/file_api_service.py @@ -601,7 +601,7 @@ def get_file_content(uid: str, file_id: str): """ e, file = FileService.get_by_id(file_id) if not e: - return False, "Document not found!" + return False, "document not found" if not check_file_team_permission(file, uid): return False, "no authorization" return True, file diff --git a/api/db/services/file_service.py b/api/db/services/file_service.py index 72728e7183..ff432dfecd 100644 --- a/api/db/services/file_service.py +++ b/api/db/services/file_service.py @@ -684,7 +684,7 @@ class FileService(CommonService): try: e, doc = DocumentService.get_by_id(doc_id) if not e: - raise Exception("Document not found!") + raise Exception("document not found") tenant_id = DocumentService.get_tenant_id(doc_id) if not tenant_id: raise Exception("Tenant not found!") diff --git a/api/utils/validation_utils.py b/api/utils/validation_utils.py index 70b3a3f47b..cc3e7cdcc9 100644 --- a/api/utils/validation_utils.py +++ b/api/utils/validation_utils.py @@ -1103,16 +1103,16 @@ def validate_immutable_fields(update_doc_req: UpdateDocumentReq, doc): or (None, None) if validation passes. """ if update_doc_req.chunk_count is not None and update_doc_req.chunk_count != int(getattr(doc, "chunk_num", -1)): - return "Can't change `chunk_count`.", RetCode.DATA_ERROR + return "can't change `chunk_count`", RetCode.DATA_ERROR if update_doc_req.token_count is not None and update_doc_req.token_count != int(getattr(doc, "token_num", -1)): - return "Can't change `token_count`.", RetCode.DATA_ERROR + return "can't change `token_count`", RetCode.DATA_ERROR if update_doc_req.progress is not None: progress_from_db = float(getattr(doc, "progress", -1.0)) # should not use "==" to compare two float values if not math.isclose(update_doc_req.progress, progress_from_db): - return "Can't change `progress`.", RetCode.DATA_ERROR + return "can't change `progress`", RetCode.DATA_ERROR return None, None diff --git a/cmd/ragflow_server.go b/cmd/ragflow_server.go index 0f19d8879d..928c08d09b 100644 --- a/cmd/ragflow_server.go +++ b/cmd/ragflow_server.go @@ -243,21 +243,21 @@ func main() { } // Temporary logger initialization - var logFile string + var logFileName string var serverName string if arguments.name != nil { serverName = *arguments.name } else { serverName = fmt.Sprintf("%s_server", *arguments.mode) } - logFile = fmt.Sprintf("%s.log", serverName) + logFileName = fmt.Sprintf("%s.log", serverName) logLevel := "info" if arguments.debugLog { logLevel = "debug" } - if err = common.InitLogger(logLevel, common.FileOutput{Path: logFile}, serverName); err != nil { + if err = common.InitLogger(logLevel, common.FileOutput{Filename: logFileName, Path: "logs"}, serverName); err != nil { panic("failed to initialize logger: " + err.Error()) } @@ -314,7 +314,9 @@ func main() { // set server name and log file path server.SetServerName(serverName) - logFile = fmt.Sprintf("%s.log", serverName) + + // rename log filename + logFileName = fmt.Sprintf("%s.log", serverName) logConfig := globalConfig.GetLogConfig() @@ -331,15 +333,13 @@ func main() { globalConfig.SetLogLevel(logLevel) fileOut := common.FileOutput{ - Path: logFile, + Filename: logFileName, + Path: logConfig.Path, MaxSize: logConfig.MaxSize, MaxBackups: logConfig.MaxBackups, MaxAge: logConfig.MaxAge, Compress: logConfig.Compress, } - if logConfig.Path != "" { - fileOut.Path = logConfig.Path - } common.SyncLog() if err = common.InitLogger(logLevel, fileOut, serverName); err != nil { diff --git a/docs/references/http_api_reference.md b/docs/references/http_api_reference.md index 9c72c0b56a..3b3a9c8fdd 100644 --- a/docs/references/http_api_reference.md +++ b/docs/references/http_api_reference.md @@ -2069,7 +2069,7 @@ Failure: ```json { "code": 102, - "message": "Document not found!" + "message": "document not found" } ``` @@ -2636,7 +2636,7 @@ Failure: ```json { "code": 102, - "message": "Document not found!" + "message": "document not found" } ``` @@ -7520,7 +7520,7 @@ Failure: ```json { "code": 404, - "message": "Document not found!" + "message": "document not found" } ``` diff --git a/internal/agent/component/begin.go b/internal/agent/component/begin.go index 03f2dec47b..fc36a59762 100644 --- a/internal/agent/component/begin.go +++ b/internal/agent/component/begin.go @@ -67,10 +67,10 @@ func (b *BeginComponent) Name() string { return b.name } func (b *BeginComponent) Invoke(ctx context.Context, db *gorm.DB, inputs map[string]any) (map[string]any, error) { state, _, err := runtime.GetStateFromContext[*runtime.CanvasState](ctx) if err != nil { - return nil, fmt.Errorf("Begin: %w", err) + return nil, fmt.Errorf("begin: %w", err) } if state == nil { - return nil, fmt.Errorf("Begin: nil canvas state") + return nil, fmt.Errorf("begin: nil canvas state") } // Query: required to drive downstream components. diff --git a/internal/agent/runtime/helpers.go b/internal/agent/runtime/helpers.go index 1a48992aea..c66c1f16ea 100644 --- a/internal/agent/runtime/helpers.go +++ b/internal/agent/runtime/helpers.go @@ -14,7 +14,7 @@ // limitations under the License. // -// Cross-cutting helpers that replace Python's `rag/flow/base.py:ProcessBase` +// Package runtime implements Cross-cutting helpers that replace Python's `rag/flow/base.py:ProcessBase` // wrapper (lines 33-63). Three call-site concerns are extracted into plain // higher-order functions: // diff --git a/internal/agent/runtime/helpers_test.go b/internal/agent/runtime/helpers_test.go index c3e941f03f..2be9315513 100644 --- a/internal/agent/runtime/helpers_test.go +++ b/internal/agent/runtime/helpers_test.go @@ -133,7 +133,7 @@ func TestTrackProgress_PassesThroughReturnValue(t *testing.T) { // err path — exact identity preserved want := errors.New("exact") got := TrackProgress("Foo", rec.callback, func() error { return want }) - if got != want { + if !errors.Is(got, want) { t.Fatalf("err not propagated by identity: got %v (%T), want %v (%T)", got, got, want, want) } diff --git a/internal/agent/tool/code_exec_contract.go b/internal/agent/tool/code_exec_contract.go index 989f353fe6..d7d98a39c6 100644 --- a/internal/agent/tool/code_exec_contract.go +++ b/internal/agent/tool/code_exec_contract.go @@ -200,7 +200,7 @@ func validateCodeExecTopLevelValueDomain(value any) error { return nil default: return fmt.Errorf( - "CodeExec unsupported top-level result type: %T. Allowed top-level values are String, Number, Boolean, Object, Array, or Null.", + "unsupported top-level result type: %T. Allowed top-level values are String, Number, Boolean, Object, Array, or Null.", value, ) } @@ -253,7 +253,7 @@ func validateCodeExecExpectedType(expectedType string, value any, path string) e case "Null": valid = value == nil default: - return fmt.Errorf("Unsupported expected type: %s", expectedType) + return fmt.Errorf("unsupported expected type: %s", expectedType) } if valid { return nil @@ -287,7 +287,7 @@ func normalizeCodeExecExpectedType(expectedType string) (string, error) { if strings.HasPrefix(low, "array<") && strings.HasSuffix(etype, ">") { inner := strings.TrimSpace(etype[len("Array<") : len(etype)-1]) if inner == "" { - return "", fmt.Errorf("Unsupported expected type: %s", expectedType) + return "", fmt.Errorf("unsupported expected type: %s", expectedType) } normalizedInner, err := normalizeCodeExecExpectedType(inner) if err != nil { diff --git a/internal/agent/tool/exesql_trino_stub.go b/internal/agent/tool/exesql_trino_stub.go index 68a56f6f75..fb929f717e 100644 --- a/internal/agent/tool/exesql_trino_stub.go +++ b/internal/agent/tool/exesql_trino_stub.go @@ -8,7 +8,7 @@ // http://www.apache.org/licenses/LICENSE-2.0 // -// exesql_trino_stub.go — minimal implementations of the Trino DSN +// Package tool implements minimal implementations of the Trino DSN // helpers referenced by exesql_trino_test.go. The real // implementation lands when the trino driver integration moves // from "registered via self-register" to "explicit DSN diff --git a/internal/agent/tool/retrieval_nlp_test.go b/internal/agent/tool/retrieval_nlp_test.go index d98f50d613..5e7c7cb983 100644 --- a/internal/agent/tool/retrieval_nlp_test.go +++ b/internal/agent/tool/retrieval_nlp_test.go @@ -28,6 +28,7 @@ package tool import ( "context" + "errors" "math" "testing" @@ -227,7 +228,7 @@ func TestNewNLPRetrievalAdapter_NilService(t *testing.T) { if err == nil { t.Fatal("expected error from nil-service adapter") } - if err != ErrRetrievalServiceMissing { + if !errors.Is(err, ErrRetrievalServiceMissing) { t.Errorf("err = %v, want ErrRetrievalServiceMissing", err) } } diff --git a/internal/agent/tool/searxng.go b/internal/agent/tool/searxng.go index 64f365442e..3dd4c79b5a 100644 --- a/internal/agent/tool/searxng.go +++ b/internal/agent/tool/searxng.go @@ -186,19 +186,19 @@ func (s *SearXNGTool) fetch(ctx context.Context, endpoint, host string, pinnedIP resp, err := s.helper.DoPinned(requestCtx, http.MethodGet, endpoint, "", "", nil, host, pinnedIP) if err != nil { - return nil, fmt.Errorf("Network error: %w", err) + return nil, fmt.Errorf("network error: %w", err) } defer resp.Body.Close() if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { - return nil, fmt.Errorf("Network error: SearXNG returned %d", resp.StatusCode) + return nil, fmt.Errorf("network error: SearXNG returned %d", resp.StatusCode) } var data map[string]any - if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { - return nil, fmt.Errorf("Invalid response from SearXNG: %w", err) + if err = json.NewDecoder(resp.Body).Decode(&data); err != nil { + return nil, fmt.Errorf("invalid response from SearXNG: %w", err) } if data == nil { - return nil, fmt.Errorf("Invalid response from SearXNG") + return nil, fmt.Errorf("invalid response from SearXNG") } rawResults, ok := data["results"] if !ok { @@ -206,11 +206,11 @@ func (s *SearXNGTool) fetch(ctx context.Context, endpoint, host string, pinnedIP } results, ok := rawResults.([]any) if !ok { - return nil, fmt.Errorf("Invalid results format from SearXNG") + return nil, fmt.Errorf("invalid results format from SearXNG") } for _, result := range results { if _, ok := result.(map[string]any); !ok { - return nil, fmt.Errorf("Invalid results format from SearXNG") + return nil, fmt.Errorf("invalid results format from SearXNG") } } return results, nil diff --git a/internal/common/format.go b/internal/common/format.go index 1aa4adc9a4..7d1ac423c4 100644 --- a/internal/common/format.go +++ b/internal/common/format.go @@ -37,7 +37,7 @@ func PtrString[T any](p *T) string { return fmt.Sprintf("%v", *p) } -// composite model name format: model_name@instance_name@provider_name +// IsCompositeModelName checks if a model name is a valid composite model name format model_name@instance_name@provider_name. func IsCompositeModelName(modelName string) bool { parts := strings.Split(modelName, "@") if len(parts) != 3 { diff --git a/internal/common/logger.go b/internal/common/logger.go index 3e694abe9a..925ddfe93a 100644 --- a/internal/common/logger.go +++ b/internal/common/logger.go @@ -48,6 +48,7 @@ var ( // applied by callers (see resolveCompress) so that "not set" can be distinguished // from "explicitly false" via the *bool LogConfig.Compress field. type FileOutput struct { + Filename string Path string MaxSize int MaxBackups int @@ -139,17 +140,15 @@ func InitLogger(level string, file FileOutput, serviceName string) error { } syncers := []zapcore.WriteSyncer{zapcore.AddSync(os.Stdout)} - if file.Path != "" { - ljLogger := &lumberjack.Logger{ - Filename: filepath.Join("logs", file.Path), - MaxSize: maxSize, - MaxBackups: maxBackups, - MaxAge: maxAge, - Compress: file.Compress, - LocalTime: true, - } - syncers = append(syncers, zapcore.AddSync(ljLogger)) + ljLogger := &lumberjack.Logger{ + Filename: filepath.Join(file.Path, file.Filename), + MaxSize: maxSize, + MaxBackups: maxBackups, + MaxAge: maxAge, + Compress: file.Compress, + LocalTime: true, } + syncers = append(syncers, zapcore.AddSync(ljLogger)) core := zapcore.NewCore( zapcore.NewConsoleEncoder(encoderConfig), diff --git a/internal/deepdoc/client_test.go b/internal/deepdoc/client_test.go index ea1f22dbdd..441f75038c 100644 --- a/internal/deepdoc/client_test.go +++ b/internal/deepdoc/client_test.go @@ -18,6 +18,7 @@ package deepdoc import ( "context" + "errors" "net/http" "net/http/httptest" "os" @@ -120,7 +121,7 @@ func TestOptions_Override(t *testing.T) { func TestClient_DLAWithoutURL(t *testing.T) { c := NewClientWithURL("") _, err := c.DLA(context.Background(), [][]byte{[]byte("jpg")}) - if err != ErrNoURL { + if !errors.Is(err, ErrNoURL) { t.Errorf("DLA() error=%v, want ErrNoURL", err) } } @@ -128,7 +129,7 @@ func TestClient_DLAWithoutURL(t *testing.T) { func TestClient_OCRReturnsNoRemoteEndpoint(t *testing.T) { c := NewClientWithURL("http://x:1") _, err := c.OCR(context.Background(), [][]byte{[]byte("jpg")}) - if err != ErrNoRemoteEndpoint { + if !errors.Is(err, ErrNoRemoteEndpoint) { t.Errorf("OCR() error=%v, want ErrNoRemoteEndpoint", err) } } @@ -136,7 +137,7 @@ func TestClient_OCRReturnsNoRemoteEndpoint(t *testing.T) { func TestClient_OCRNoRemoteEndpointEvenWithUnsetURL(t *testing.T) { c := NewClientWithURL("") _, err := c.OCR(context.Background(), nil) - if err != ErrNoRemoteEndpoint { + if !errors.Is(err, ErrNoRemoteEndpoint) { t.Errorf("OCR() error=%v, want ErrNoRemoteEndpoint (call should not fall through to ErrNoURL)", err) } } @@ -144,7 +145,7 @@ func TestClient_OCRNoRemoteEndpointEvenWithUnsetURL(t *testing.T) { func TestClient_TSRReturnsNoRemoteEndpoint(t *testing.T) { c := NewClientWithURL("http://x:1") _, err := c.TSR(context.Background(), [][]byte{[]byte("jpg")}) - if err != ErrNoRemoteEndpoint { + if !errors.Is(err, ErrNoRemoteEndpoint) { t.Errorf("TSR() error=%v, want ErrNoRemoteEndpoint", err) } } diff --git a/internal/deepdoc/parser/pdf/layout/boxes_sections.go b/internal/deepdoc/parser/pdf/layout/boxes_sections.go index 84cd19227c..5b5cc73f35 100644 --- a/internal/deepdoc/parser/pdf/layout/boxes_sections.go +++ b/internal/deepdoc/parser/pdf/layout/boxes_sections.go @@ -43,7 +43,7 @@ func ResolvePageSpan(pageNum int, bottom float64, pageHeights map[int]float64) ( return } -// boxesToSections converts layout boxes to section format with position tags. +// BoxesToSections converts layout boxes to section format with position tags. // // pageHeights provides the PDF-point height of each page (image height / zoom). // Boxes that extend beyond their page produce multi-page position tags diff --git a/internal/deepdoc/parser/pdf/layout/chars_boxes.go b/internal/deepdoc/parser/pdf/layout/chars_boxes.go index c25f684a7f..4586f734e4 100644 --- a/internal/deepdoc/parser/pdf/layout/chars_boxes.go +++ b/internal/deepdoc/parser/pdf/layout/chars_boxes.go @@ -122,7 +122,7 @@ func splitLineByXGap(chars []pdf.TextChar, threshold float64) [][]pdf.TextChar { // ---- internal helpers ---- -// groupCharsToLines groups characters into horizontal lines based on vertical overlap. +// GroupCharsToLines groups characters into horizontal lines based on vertical overlap. func GroupCharsToLines(chars []pdf.TextChar, sortByTop bool) [][]pdf.TextChar { if len(chars) == 0 { return nil diff --git a/internal/deepdoc/parser/pdf/tool/compare.go b/internal/deepdoc/parser/pdf/tool/compare.go index 0e169965cb..c62ea849be 100644 --- a/internal/deepdoc/parser/pdf/tool/compare.go +++ b/internal/deepdoc/parser/pdf/tool/compare.go @@ -328,7 +328,7 @@ func cellName(col, row int) string { return s } -// including per-cell text comparison. +// CompareTablesWithPython including per-cell text comparison. func CompareTablesWithPython(log TLogger, goTablesDir, pyTablesDir string) { goEntries, err := os.ReadDir(goTablesDir) if err != nil { diff --git a/internal/deepdoc/parser/pdf/util/crop.go b/internal/deepdoc/parser/pdf/util/crop.go index f770fe1bb3..214679b0f3 100644 --- a/internal/deepdoc/parser/pdf/util/crop.go +++ b/internal/deepdoc/parser/pdf/util/crop.go @@ -240,7 +240,7 @@ func CropSectionImage(posTag string, decodedImages map[int]image.Image, zoom flo return base64.StdEncoding.EncodeToString(data) } -// cropSectionByDLA crops a section using the best-overlapping DLA region, +// CropSectionByDLA crops a section using the best-overlapping DLA region, // mimicking Python's cropout() in deepdoc/parser/pdf_parser.py (around line // 1307). Unlike the original Go version (which only cropped the first page), // it now walks every position and every page the section spans, crops each @@ -483,7 +483,7 @@ func rotateCoordCW(x, y float64, origW, origH int, angle int) (float64, float64) } } -// rotateImageCW rotates an image clockwise. Only 0/90/180/270 supported; +// RotateImageCW rotates an image clockwise. Only 0/90/180/270 supported; // other values return nil. Matches Python PIL.Image.rotate(-angle, expand=True). func RotateImageCW(img image.Image, angle int) *image.RGBA { b := img.Bounds() @@ -509,7 +509,7 @@ func RotateImageCW(img image.Image, angle int) *image.RGBA { return dst } -// mapRotatedPointToOriginal maps a point from rotated image coords back to +// MapRotatedPointToOriginal maps a point from rotated image coords back to // original coords. angle is the clockwise rotation applied. origW, origH // are the ORIGINAL (pre-rotation) image dimensions. // diff --git a/internal/deepdoc/parser/pdf/util/geometry.go b/internal/deepdoc/parser/pdf/util/geometry.go index 66ed7ad26c..65d3f98875 100644 --- a/internal/deepdoc/parser/pdf/util/geometry.go +++ b/internal/deepdoc/parser/pdf/util/geometry.go @@ -189,7 +189,7 @@ func RectOverlap(a, b Rect) float64 { return OverlapRatioMax(a, b) } -// fastCrop copies a rectangular region from src to a new *image.RGBA. +// FastCrop copies a rectangular region from src to a new *image.RGBA. // Uses direct Pix slice copy for *image.RGBA sources (zero allocation per row); // falls back to pixel-by-pixel for other image types. func FastCrop(src image.Image, x0, y0, x1, y1 int) *image.RGBA { diff --git a/internal/engine/elasticsearch/chunk_helpers_test.go b/internal/engine/elasticsearch/chunk_helpers_test.go index 60afe15a1a..261f4aaaf9 100644 --- a/internal/engine/elasticsearch/chunk_helpers_test.go +++ b/internal/engine/elasticsearch/chunk_helpers_test.go @@ -122,12 +122,13 @@ func TestElasticsearchGetFieldsEmptyAndSkippedIDs(t *testing.T) { if _, ok := got["missing-id.md"]; ok { t.Fatalf("chunk without id should be skipped: %#v", got) } - if fallbackMap, ok := got["fallback-chunk"]; !ok { + fallbackMap, ok := got["fallback-chunk"] + if !ok { t.Fatalf("GetFields keys=%v, want fallback-chunk", got) - } else { - assertEqual(t, fallbackMap["id"], "fallback-chunk") - assertEqual(t, fallbackMap["docnm_kwd"], "fallback.md") } + + assertEqual(t, fallbackMap["id"], "fallback-chunk") + assertEqual(t, fallbackMap["docnm_kwd"], "fallback.md") } func TestElasticsearchGetAggregationSplitsCountsAndSorts(t *testing.T) { diff --git a/internal/engine/elasticsearch/client.go b/internal/engine/elasticsearch/client.go index e63cb36b6f..4d717092b6 100644 --- a/internal/engine/elasticsearch/client.go +++ b/internal/engine/elasticsearch/client.go @@ -68,7 +68,7 @@ func NewEngine(esConfig config.ElasticsearchConfig) (*Engine, error) { defer res.Body.Close() if res.IsError() { - return nil, fmt.Errorf("Elasticsearch returned error: %s", res.Status()) + return nil, fmt.Errorf("elasticsearch returned error: %s", res.Status()) } engine := &Engine{ diff --git a/internal/engine/infinity/chunk.go b/internal/engine/infinity/chunk.go index bc977c52b1..17963ffb94 100644 --- a/internal/engine/infinity/chunk.go +++ b/internal/engine/infinity/chunk.go @@ -274,7 +274,7 @@ func (e *Engine) InsertChunks(ctx context.Context, chunks []map[string]interface db, release, err := e.client.checkoutDatabase(ctx, "chunk.go") if err != nil { - return nil, fmt.Errorf("Failed to get database: %w", err) + return nil, fmt.Errorf("failed to get database: %w", err) } defer release() @@ -283,7 +283,7 @@ func (e *Engine) InsertChunks(ctx context.Context, chunks []map[string]interface // Table doesn't exist, try to create it errMsg := strings.ToLower(err.Error()) if !strings.Contains(errMsg, "not found") && !strings.Contains(errMsg, "doesn't exist") { - return nil, fmt.Errorf("Failed to get table %s: %w", tableName, err) + return nil, fmt.Errorf("failed to get table %s: %w", tableName, err) } // Infer vector size from chunks @@ -313,12 +313,12 @@ func (e *Engine) InsertChunks(ctx context.Context, chunks []map[string]interface // Create table if err := e.createChunkStoreWithDB(db, baseName, datasetID, vectorSize, parserID); err != nil { - return nil, fmt.Errorf("Failed to create table: %w", err) + return nil, fmt.Errorf("failed to create table: %w", err) } table, err = db.GetTable(tableName) if err != nil { - return nil, fmt.Errorf("Failed to get table after creation: %w", err) + return nil, fmt.Errorf("failed to get table after creation: %w", err) } } @@ -326,7 +326,7 @@ func (e *Engine) InsertChunks(ctx context.Context, chunks []map[string]interface var embeddingCols [][2]interface{} colsResp, err := table.ShowColumns() if err != nil { - return nil, fmt.Errorf("Failed to get columns: %w", err) + return nil, fmt.Errorf("failed to get columns: %w", err) } result, ok := colsResp.(*infinity.QueryResult) if !ok { @@ -379,14 +379,14 @@ func (e *Engine) InsertChunks(ctx context.Context, chunks []map[string]interface // Insert chunks to dataset _, err = table.Insert(insertChunks) if err != nil { - return nil, fmt.Errorf("Failed to insert chunks to dataset: %w", err) + return nil, fmt.Errorf("failed to insert chunks to dataset: %w", err) } common.Info("InfinityConnection.InsertChunks result", zap.String("tableName", tableName), zap.Int("count", len(insertChunks))) return []string{}, nil } -// UpdateChunks updates chunks in a dataset table +// UpdateChunks updates chunks in a dataset // Table name format: {baseName}_{datasetID} func (e *Engine) UpdateChunks(ctx context.Context, condition map[string]interface{}, newValue map[string]interface{}, baseName string, datasetID string) error { tableName := buildChunkTableName(baseName, datasetID) @@ -394,7 +394,7 @@ func (e *Engine) UpdateChunks(ctx context.Context, condition map[string]interfac db, release, err := e.client.checkoutDatabase(ctx, "chunk.go") if err != nil { - return fmt.Errorf("Failed to get database: %w", err) + return fmt.Errorf("failed to get database: %w", err) } defer release() @@ -406,7 +406,7 @@ func (e *Engine) UpdateChunks(ctx context.Context, condition map[string]interfac if strings.Contains(errMsg, "not found") || strings.Contains(errMsg, "doesn't exist") { return nil } - return fmt.Errorf("Failed to get table %s: %w", tableName, err) + return fmt.Errorf("failed to get table %s: %w", tableName, err) } // Get table columns @@ -416,7 +416,7 @@ func (e *Engine) UpdateChunks(ctx context.Context, condition map[string]interfac }) colsResp, err := table.ShowColumns() if err != nil { - return fmt.Errorf("Failed to get columns: %w", err) + return fmt.Errorf("failed to get columns: %w", err) } result, ok := colsResp.(*infinity.QueryResult) if ok { @@ -534,7 +534,7 @@ func (e *Engine) UpdateChunks(ctx context.Context, condition map[string]interfac common.Info(fmt.Sprintf("INFINITY update: table=%s, filter=%s, newValue=%v", tableName, filter, newValue)) _, err = table.Update(filter, newValue) if err != nil { - return fmt.Errorf("Failed to update chunks: %w", err) + return fmt.Errorf("failed to update chunks: %w", err) } common.Info("InfinityConnection.UpdateChunks completes", zap.String("tableName", tableName)) @@ -553,7 +553,7 @@ func (e *Engine) AdjustChunkPagerank(ctx context.Context, baseName, chunkID, dat ctx = context.Background() } if e.client == nil || e.client.pool == nil { - return fmt.Errorf("Infinity client not initialized") + return fmt.Errorf("infinity client not initialized") } tableName := buildChunkTableName(baseName, datasetID) @@ -1214,7 +1214,7 @@ func (e *Engine) Search(ctx context.Context, req *types.SearchRequest) (*types.S // GetChunk gets a chunk by ID func (e *Engine) GetChunk(ctx context.Context, tableName, chunkID string, datasetIDs []string) (interface{}, error) { if e.client == nil || e.client.pool == nil { - return nil, fmt.Errorf("Infinity client not initialized") + return nil, fmt.Errorf("infinity client not initialized") } common.Info("Infinity get chunk start", diff --git a/internal/engine/infinity/client.go b/internal/engine/infinity/client.go index d6c3edf215..6316a8cad5 100644 --- a/internal/engine/infinity/client.go +++ b/internal/engine/infinity/client.go @@ -173,7 +173,7 @@ func NewInfinityClient(cfg config.InfinityConfig) (*infinityClient, error) { } } if err != nil { - return nil, fmt.Errorf("Failed to connect to Infinity after 120s: %w", err) + return nil, fmt.Errorf("failed to connect to Infinity after 120s: %w", err) } client := &infinityClient{ @@ -243,12 +243,12 @@ func (c *infinityClient) WaitForHealthy(ctx context.Context, timeout time.Durati } time.Sleep(5 * time.Second) } - return fmt.Errorf("Infinity not healthy after %v", timeout) + return fmt.Errorf("infinity not healthy after %v", timeout) } func (c *infinityClient) checkoutConn(ctx context.Context, caller string) (*infinity.InfinityConnection, func(), error) { if c == nil || c.pool == nil { - return nil, nil, fmt.Errorf("Infinity client not initialized") + return nil, nil, fmt.Errorf("infinity client not initialized") } ctx, cancel := ensureDeadline(ctx, defaultOperationTimeout) conn, err := c.pool.GetContext(ctx) @@ -365,7 +365,7 @@ func NewEngine(infinityConfig config.InfinityConfig) (*Engine, error) { // Wait for Infinity to be healthy if err = client.WaitForHealthy(context.Background(), 120*time.Second); err != nil { - return nil, fmt.Errorf("Infinity not healthy: %w", err) + return nil, fmt.Errorf("infinity not healthy: %w", err) } // MigrateDB creates the database if it doesn't exist @@ -389,7 +389,7 @@ func (e *Engine) SupportsPageRank() bool { // Ping checks if Infinity is accessible func (e *Engine) Ping(ctx context.Context) error { if e.client == nil || e.client.pool == nil { - return fmt.Errorf("Infinity client not initialized") + return fmt.Errorf("infinity client not initialized") } conn, release, err := e.client.checkoutConn(ctx, "Ping") if err != nil { @@ -397,7 +397,7 @@ func (e *Engine) Ping(ctx context.Context) error { } defer release() if !conn.IsConnected() { - return fmt.Errorf("Infinity not connected") + return fmt.Errorf("infinity not connected") } return nil } diff --git a/internal/engine/redis/redis.go b/internal/engine/redis/redis.go index 24e1d86c6c..0bf424e604 100644 --- a/internal/engine/redis/redis.go +++ b/internal/engine/redis/redis.go @@ -19,6 +19,7 @@ package redis import ( "context" "encoding/json" + "errors" "fmt" "math" "math/rand" @@ -294,7 +295,7 @@ func (r *Client) Get(ctx context.Context, key string) (string, error) { return "", nil } val, err := r.client.Get(ctx, key).Result() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return "", nil } if err != nil { @@ -327,7 +328,7 @@ func (r *Client) GetObj(ctx context.Context, key string, dest interface{}) bool return false } data, err := r.client.Get(ctx, key).Result() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return false } if err != nil { @@ -675,7 +676,7 @@ func (r *Client) QueueConsumer(ctx context.Context, queueName, groupName, consum Block: 5 * time.Second, }).Result() - if err == redis.Nil { + if errors.Is(err, redis.Nil) { return nil, nil } if err != nil { diff --git a/internal/entity/chat.go b/internal/entity/chat.go index d169e3ecd8..5ccebbb7eb 100644 --- a/internal/entity/chat.go +++ b/internal/entity/chat.go @@ -62,7 +62,7 @@ type ChatListItem struct { TenantAvatar *string `gorm:"column:tenant_avatar" json:"tenant_avatar,omitempty"` } -// Conversation conversation model +// ChatSession chat session model type ChatSession struct { ID string `gorm:"column:id;primaryKey;size:32" json:"id"` DialogID string `gorm:"column:dialog_id;size:32;not null;index" json:"dialog_id"` diff --git a/internal/entity/models/302ai.go b/internal/entity/models/302ai.go index 8d12eb49e2..d899e16a9d 100644 --- a/internal/entity/models/302ai.go +++ b/internal/entity/models/302ai.go @@ -86,7 +86,7 @@ func (a *AI302Model) ChatWithMessages(ctx context.Context, modelName string, mes if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Chat) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Chat) // Build request body reqBody := buildRequestBody(chatModelConfig, strings.TrimSpace(modelName), messages, false) @@ -112,7 +112,7 @@ func (a *AI302Model) ChatWithMessages(ctx context.Context, modelName string, mes } } - body, err := a.baseModel.doRequest(ctx, url, apiConfig, reqBody, nonStreamCallTimeout) + body, err := a.baseModel.doRequest(ctx, baseURL, apiConfig, reqBody, nonStreamCallTimeout) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (a *AI302Model) ChatStreamlyWithSender(ctx context.Context, modelName strin if err != nil { return err } - url := fmt.Sprintf("%s/%s", strings.TrimSuffix(resolvedBaseURL, "/"), a.baseModel.URLSuffix.Chat) + baseURL := fmt.Sprintf("%s/%s", strings.TrimSuffix(resolvedBaseURL, "/"), a.baseModel.URLSuffix.Chat) // Build request body with streaming enabled reqBody := buildRequestBody(modelConfig, strings.TrimSpace(modelName), messages, true) @@ -166,7 +166,7 @@ func (a *AI302Model) ChatStreamlyWithSender(ctx context.Context, modelName strin reqBody["stream_options"] = map[string]interface{}{"include_usage": true} - return a.baseModel.doStreamRequest(ctx, url, apiConfig, reqBody, streamCallTimeout, func(body io.ReadCloser) error { + return a.baseModel.doStreamRequest(ctx, baseURL, apiConfig, reqBody, streamCallTimeout, func(body io.ReadCloser) error { return HandleStreamingResponse(body, modelUsage, modelConfig, OpenAIParserConfig, sender) }) } @@ -188,7 +188,7 @@ func (a *AI302Model) Embed(ctx context.Context, modelName *string, texts []strin if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Embedding) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Embedding) reqBody := map[string]interface{}{ "model": model, @@ -203,7 +203,7 @@ func (a *AI302Model) Embed(ctx context.Context, modelName *string, texts []strin ctx, cancel := context.WithTimeout(ctx, nonStreamCallTimeout) defer cancel() - req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData)) + req, err := http.NewRequestWithContext(ctx, "POST", baseURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } @@ -223,7 +223,7 @@ func (a *AI302Model) Embed(ctx context.Context, modelName *string, texts []strin } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Jina embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("JINA embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsedResponse struct { @@ -238,7 +238,7 @@ func (a *AI302Model) Embed(ctx context.Context, modelName *string, texts []strin } if len(parsedResponse.Data) == 0 { - return nil, fmt.Errorf("Jina embedding response contains no data: %s", string(body)) + return nil, fmt.Errorf("JINA embedding response contains no data: %s", string(body)) } var embeddings []EmbeddingData @@ -273,7 +273,7 @@ func (a *AI302Model) Rerank(ctx context.Context, modelName *string, query string if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Rerank) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Rerank) var topN int if rerankConfig != nil && rerankConfig.TopN != 0 { @@ -295,7 +295,7 @@ func (a *AI302Model) Rerank(ctx context.Context, modelName *string, query string ctx, cancel := context.WithTimeout(ctx, nonStreamCallTimeout) defer cancel() - req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData)) + req, err := http.NewRequestWithContext(ctx, "POST", baseURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } @@ -359,7 +359,7 @@ func (a *AI302Model) TranscribeAudio(ctx context.Context, modelName *string, fil if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.ASR) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.ASR) // multipart body var body bytes.Buffer @@ -432,7 +432,7 @@ func (a *AI302Model) TranscribeAudio(ctx context.Context, modelName *string, fil ctx, cancel := context.WithTimeout(ctx, longOpCallTimeout) defer cancel() - req, err := http.NewRequestWithContext(ctx, "POST", url, &body) + req, err := http.NewRequestWithContext(ctx, "POST", baseURL, &body) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } @@ -500,7 +500,7 @@ func (a *AI302Model) OCRFile(ctx context.Context, modelName *string, content []b if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.OCR) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.OCR) var docURL string if urls != nil && strings.TrimSpace(*urls) != "" { @@ -530,7 +530,7 @@ func (a *AI302Model) OCRFile(ctx context.Context, modelName *string, content []b ctx, cancel := context.WithTimeout(ctx, longOpCallTimeout) defer cancel() - req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData)) + req, err := http.NewRequestWithContext(ctx, "POST", baseURL, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } @@ -550,7 +550,7 @@ func (a *AI302Model) OCRFile(ctx context.Context, modelName *string, content []b } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Mistral OCR API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("MISTRAL OCR API error: %s, body: %s", resp.Status, string(body)) } var mistralResp struct { @@ -659,12 +659,12 @@ func (a *AI302Model) ListModels(ctx context.Context, apiConfig *APIConfig) ([]Li if err != nil { return nil, err } - url := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Models) + baseURL := fmt.Sprintf("%s/%s", resolvedBaseURL, a.baseModel.URLSuffix.Models) ctx, cancel := context.WithTimeout(ctx, nonStreamCallTimeout) defer cancel() - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + req, err := http.NewRequestWithContext(ctx, "GET", baseURL, nil) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } diff --git a/internal/entity/models/aliyun.go b/internal/entity/models/aliyun.go index 8d74744c3d..5e50a1a640 100644 --- a/internal/entity/models/aliyun.go +++ b/internal/entity/models/aliyun.go @@ -256,7 +256,7 @@ func (a *AliyunModel) Embed(ctx context.Context, modelName *string, texts []stri } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Aliyun embeddings API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("aliyun embeddings API error: %s, body: %s", resp.Status, string(body)) } var parsed aliyunEmbeddingResponse @@ -362,7 +362,7 @@ func (a *AliyunModel) Rerank(ctx context.Context, modelName *string, query strin } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Aliyun rerank API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("aliyun rerank API error: %s, body: %s", resp.Status, string(body)) } var parsed aliyunRerankResponse diff --git a/internal/entity/models/anthropic.go b/internal/entity/models/anthropic.go index 8513d319ae..8fedf06d2b 100644 --- a/internal/entity/models/anthropic.go +++ b/internal/entity/models/anthropic.go @@ -122,7 +122,7 @@ func (a *AnthropicModel) ChatWithMessages(ctx context.Context, modelName string, return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Anthropic messages API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("anthropic messages API error: %s, body: %s", resp.Status, string(body)) } answer, reasoning, err := parseAnthropicChatResponse(body) @@ -410,7 +410,7 @@ func (a *AnthropicModel) ListModels(ctx context.Context, apiConfig *APIConfig) ( return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Anthropic models API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("anthropic models API error: %s, body: %s", resp.Status, string(body)) } var result struct { @@ -496,7 +496,7 @@ func (a *AnthropicModel) ChatStreamlyWithSender(ctx context.Context, modelName s if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) - return fmt.Errorf("Anthropic messages API error: %s, body: %s", resp.Status, string(body)) + return fmt.Errorf("anthropic messages API error: %s, body: %s", resp.Status, string(body)) } sawTerminal := false @@ -551,7 +551,7 @@ func (a *AnthropicModel) ChatStreamlyWithSender(ctx context.Context, modelName s case "error": errInfo, _ := event["error"].(map[string]interface{}) message, _ := errInfo["message"].(string) - return fmt.Errorf("Anthropic stream error: %s", message) + return fmt.Errorf("anthropic stream error: %s", message) } return nil }) diff --git a/internal/entity/models/astraflow.go b/internal/entity/models/astraflow.go index 063a25321e..f526f93432 100644 --- a/internal/entity/models/astraflow.go +++ b/internal/entity/models/astraflow.go @@ -229,7 +229,7 @@ func (a *AstraflowModel) Embed(ctx context.Context, modelName *string, texts []s } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Astraflow embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("astraflow embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsedResponse struct { @@ -244,7 +244,7 @@ func (a *AstraflowModel) Embed(ctx context.Context, modelName *string, texts []s } if len(parsedResponse.Data) == 0 { - return nil, fmt.Errorf("Astraflow embedding response contains no data: %s", string(body)) + return nil, fmt.Errorf("astraflow embedding response contains no data: %s", string(body)) } var embeddings []EmbeddingData @@ -310,7 +310,7 @@ func (a *AstraflowModel) Rerank(ctx context.Context, modelName *string, query st } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Astraflow Rerank API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("astraflow Rerank API error: status %d, body: %s", resp.StatusCode, string(body)) } var rerankResp struct { diff --git a/internal/entity/models/azure_openai.go b/internal/entity/models/azure_openai.go index cb56ac9868..250da4eddc 100644 --- a/internal/entity/models/azure_openai.go +++ b/internal/entity/models/azure_openai.go @@ -295,7 +295,7 @@ func (a *AzureOpenAIModel) Embed(ctx context.Context, modelName *string, texts [ } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Azure OpenAI embeddings API error: %s, body: %s", resp.Status, string(body)) + return nil, fmt.Errorf("azure OpenAI embeddings API error: %s, body: %s", resp.Status, string(body)) } var parsed azureEmbeddingResponse diff --git a/internal/entity/models/baichuan.go b/internal/entity/models/baichuan.go index dc81ce9ce5..872f9c11bb 100644 --- a/internal/entity/models/baichuan.go +++ b/internal/entity/models/baichuan.go @@ -143,7 +143,7 @@ func (b *BaichuanModel) Embed(ctx context.Context, modelName *string, texts []st } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Baichuan embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("baichuan embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsedResponse struct { @@ -163,7 +163,7 @@ func (b *BaichuanModel) Embed(ctx context.Context, modelName *string, texts []st } if len(parsedResponse.Data) == 0 { - return nil, fmt.Errorf("Baichuan embedding response contains no data: %s", string(body)) + return nil, fmt.Errorf("baichuan embedding response contains no data: %s", string(body)) } var embeddings []EmbeddingData diff --git a/internal/entity/models/baidu.go b/internal/entity/models/baidu.go index 3b86a1f702..31e4a8b0ae 100644 --- a/internal/entity/models/baidu.go +++ b/internal/entity/models/baidu.go @@ -258,7 +258,7 @@ func (b *BaiduModel) Embed(ctx context.Context, modelName *string, texts []strin } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Baidu embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("baidu embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsed baiduEmbeddingResponse @@ -357,7 +357,7 @@ func (b *BaiduModel) Rerank(ctx context.Context, modelName *string, query string } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Baidu rerank API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("baidu rerank API error: status %d, body: %s", resp.StatusCode, string(body)) } var rerankResp struct { diff --git a/internal/entity/models/builtin.go b/internal/entity/models/builtin.go index cdefc00794..48b2e1a51f 100644 --- a/internal/entity/models/builtin.go +++ b/internal/entity/models/builtin.go @@ -103,7 +103,7 @@ func (b *BuiltinModel) Embed(ctx context.Context, modelName *string, texts []str } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Builtin embeddings API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("builtin embeddings API error: status %d, body: %s", resp.StatusCode, string(body)) } // TEI returns a simple array of embeddings by default diff --git a/internal/entity/models/cohere.go b/internal/entity/models/cohere.go index 5e872bbede..d493338586 100644 --- a/internal/entity/models/cohere.go +++ b/internal/entity/models/cohere.go @@ -197,7 +197,7 @@ func (c *CoHereModel) ChatWithMessages(ctx context.Context, modelName string, me } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Cohere chat API error: %d %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("cohere chat API error: %d %s", resp.StatusCode, string(body)) } return parseChatCompletionResponse(body, chatModelConfig, modelUsage, func(body []byte, chatConfig *ChatConfig) (chatResponseParts, error) { @@ -289,7 +289,7 @@ func (c *CoHereModel) ChatStreamlyWithSender(ctx context.Context, modelName stri if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) - return fmt.Errorf("Cohere stream API error %d: %s", resp.StatusCode, string(body)) + return fmt.Errorf("cohere stream API error %d: %s", resp.StatusCode, string(body)) } sawTerminal := false @@ -348,7 +348,7 @@ func (c *CoHereModel) ChatStreamlyWithSender(ctx context.Context, modelName stri return fmt.Errorf("failed to scan response body: %w", err) } if !done && !sawTerminal { - return fmt.Errorf("Cohere: stream ended before [DONE] or finish_reason") + return fmt.Errorf("cohere: stream ended before [DONE] or finish_reason") } setSortedToolCallsResult(modelConfig, accumulatedToolCalls) @@ -414,7 +414,7 @@ func (c *CoHereModel) Embed(ctx context.Context, modelName *string, texts []stri } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Cohere embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("cohere embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var result struct { @@ -434,7 +434,7 @@ func (c *CoHereModel) Embed(ctx context.Context, modelName *string, texts []stri } if len(result.Embeddings.Float) == 0 { - return nil, fmt.Errorf("Cohere embedding response contains no float data: %s", string(body)) + return nil, fmt.Errorf("cohere embedding response contains no float data: %s", string(body)) } var embeddings []EmbeddingData @@ -507,7 +507,7 @@ func (c *CoHereModel) Rerank(ctx context.Context, modelName *string, query strin } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Cohere rerank API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("cohere rerank API error: status %d, body: %s", resp.StatusCode, string(body)) } var rerankResp struct { @@ -643,7 +643,7 @@ func (c *CoHereModel) TranscribeAudio(ctx context.Context, modelName *string, fi } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Cohere ASR API error: status %d, body: %s", resp.StatusCode, string(respBody)) + return nil, fmt.Errorf("cohere ASR API error: status %d, body: %s", resp.StatusCode, string(respBody)) } var result struct { @@ -714,7 +714,7 @@ func (c *CoHereModel) ListModels(ctx context.Context, apiConfig *APIConfig) ([]L } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Cohere API request failed with status %d: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("cohere API request failed with status %d: %s", resp.StatusCode, string(body)) } // Parse response diff --git a/internal/entity/models/huaweicloud.go b/internal/entity/models/huaweicloud.go index 4368348095..dbbdd4c546 100644 --- a/internal/entity/models/huaweicloud.go +++ b/internal/entity/models/huaweicloud.go @@ -321,7 +321,7 @@ func (h *HuaweiCloudModel) Embed(ctx context.Context, modelName *string, texts [ return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Huawei Cloud embedding API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("huawei cloud embedding API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsed huaweiCloudEmbeddingResponse @@ -426,7 +426,7 @@ func (h *HuaweiCloudModel) Rerank(ctx context.Context, modelName *string, query return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Huawei Cloud rerank API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("huawei cloud rerank API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsed huaweiCloudRerankResponse @@ -521,7 +521,7 @@ func (h *HuaweiCloudModel) ListModels(ctx context.Context, apiConfig *APIConfig) return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("Huawei Cloud models API error: status %d, body: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("huawei cloud models API error: status %d, body: %s", resp.StatusCode, string(body)) } var parsed struct { diff --git a/internal/handler/agent.go b/internal/handler/agent.go index c2bdd64f4d..6ba8cacc26 100644 --- a/internal/handler/agent.go +++ b/internal/handler/agent.go @@ -394,13 +394,13 @@ func (h *AgentHandler) UpdateAgent(c *gin.Context) { common.ResponseWithCodeData(c, ec, nil, em) return } - canvas, err := h.agentService.GetAgent(c.Request.Context(), user.ID, canvasID) - if err != nil || canvas == nil { + canvasInstance, err := h.agentService.GetAgent(c.Request.Context(), user.ID, canvasID) + if err != nil || canvasInstance == nil { common.SuccessWithData(c, map[string]interface{}{}, "success") return } common.SuccessWithData(c, map[string]interface{}{ - "update_time": canvas.UpdateTime, + "update_time": canvasInstance.UpdateTime, }, "success") } diff --git a/internal/handler/agent_component.go b/internal/handler/agent_component.go index 6ee2181e02..b79973204c 100644 --- a/internal/handler/agent_component.go +++ b/internal/handler/agent_component.go @@ -59,7 +59,7 @@ func (h *AgentHandler) GetComponentInputForm(c *gin.Context) { cv, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID) if err != nil { - if err == dao.ErrUserCanvasNotFound { + if errors.Is(err, dao.ErrUserCanvasNotFound) { common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } @@ -144,7 +144,7 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { cv, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID) if err != nil { - if err == dao.ErrUserCanvasNotFound { + if errors.Is(err, dao.ErrUserCanvasNotFound) { common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } diff --git a/internal/handler/agent_upload.go b/internal/handler/agent_upload.go index 987e164859..295a542da1 100644 --- a/internal/handler/agent_upload.go +++ b/internal/handler/agent_upload.go @@ -34,6 +34,7 @@ package handler import ( + "errors" "net/http" "github.com/gin-gonic/gin" @@ -74,7 +75,7 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { // (103) with the python permission message so existing clients can // still pattern-match the text. if _, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID); err != nil { - if err == dao.ErrUserCanvasNotFound { + if errors.Is(err, dao.ErrUserCanvasNotFound) { common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } diff --git a/internal/handler/agent_webhook_security.go b/internal/handler/agent_webhook_security.go index 3e19248d2a..1fcd479ffb 100644 --- a/internal/handler/agent_webhook_security.go +++ b/internal/handler/agent_webhook_security.go @@ -85,7 +85,7 @@ const ( // fail-closed default. PR review round 5 (#2) — the previous // form leaked that distinction via two different messages. var errWebhookFailClosed = errors.New( - "webhook security is required. Set allow_anonymous to true to permit unauthenticated webhooks.", + "webhook security is required. Set allow_anonymous to true to permit unauthenticated webhooks", ) // validateWebhookSecurity is the orchestrator. @@ -362,15 +362,15 @@ func isTruthyAllowAnonymous(cfg map[string]any) bool { func validateTokenAuth(c *gin.Context, cfg map[string]any) error { rawToken, _ := cfg["token"].(map[string]any) if rawToken == nil { - return fmt.Errorf("Invalid token authentication") + return fmt.Errorf("invalid token authentication") } header, _ := rawToken["token_header"].(string) want, _ := rawToken["token_value"].(string) if header == "" || want == "" { - return fmt.Errorf("Invalid token authentication") + return fmt.Errorf("invalid token authentication") } if c.GetHeader(header) != want { - return fmt.Errorf("Invalid token authentication") + return fmt.Errorf("invalid token authentication") } return nil } @@ -382,16 +382,16 @@ func validateTokenAuth(c *gin.Context, cfg map[string]any) error { func validateBasicAuth(c *gin.Context, cfg map[string]any) error { rawBasic, _ := cfg["basic_auth"].(map[string]any) if rawBasic == nil { - return fmt.Errorf("Invalid Basic Auth credentials") + return fmt.Errorf("invalid basic auth credentials") } username, _ := rawBasic["username"].(string) password, _ := rawBasic["password"].(string) if username == "" || password == "" { - return fmt.Errorf("Invalid Basic Auth credentials") + return fmt.Errorf("invalid basic auth credentials") } u, p, ok := c.Request.BasicAuth() if !ok || u != username || p != password { - return fmt.Errorf("Invalid Basic Auth credentials") + return fmt.Errorf("invalid basic auth credentials") } return nil } diff --git a/internal/handler/agent_webhook_test.go b/internal/handler/agent_webhook_test.go index 3f08cad01e..624a23f080 100644 --- a/internal/handler/agent_webhook_test.go +++ b/internal/handler/agent_webhook_test.go @@ -266,8 +266,8 @@ func TestWebhook_TokenAuthFails(t *testing.T) { if code != int(common.CodeDataError) { t.Errorf("code = %d, want %d", code, common.CodeDataError) } - if msg != "Invalid token authentication" { - t.Errorf("message = %q, want %q", msg, "Invalid token authentication") + if msg != "invalid token authentication" { + t.Errorf("message = %q, want %q", msg, "invalid token authentication") } } diff --git a/internal/handler/bot_test.go b/internal/handler/bot_test.go index 2e98453141..ff2b77a990 100644 --- a/internal/handler/bot_test.go +++ b/internal/handler/bot_test.go @@ -190,7 +190,7 @@ func TestChatbotInfo_HasTavilyKey(t *testing.T) { func TestChatbotInfo_ForeignTenant(t *testing.T) { stub := &stubBotService{ chatbotInfoFn: func(ctx context.Context, tenantID, dialogID string) (string, string, string, string, bool, common.ErrorCode, error) { - return "", "", "", "", false, common.CodeDataError, errors.New("Authentication error: no access to this chatbot!") + return "", "", "", "", false, common.CodeDataError, errors.New("authentication error: no access to this chatbot") }, } r := botTestEngine(stub) @@ -484,7 +484,7 @@ func TestAgentbotCompletion_URLBoundAgentID(t *testing.T) { func TestAgentbotCompletion_NoAccess(t *testing.T) { stub := &stubBotService{ agentbotCompleteFn: func(ctx context.Context, tenantID, agentID string, req service.AgentbotCompletionRequest) (<-chan canvas.RunEvent, common.ErrorCode, error) { - return nil, common.CodeDataError, errors.New("Can't find agent by ID: a1") + return nil, common.CodeDataError, errors.New("can't find agent by ID: a1") }, } r := botTestEngine(stub) @@ -497,8 +497,8 @@ func TestAgentbotCompletion_NoAccess(t *testing.T) { if resp.Code != 102 { t.Errorf("code = %d, want 102", resp.Code) } - if !strings.Contains(resp.Message, "Can't find agent") { - t.Errorf("message = %q, want contains 'Can't find agent'", resp.Message) + if !strings.Contains(resp.Message, "can't find agent") { + t.Errorf("message = %q, want contains 'can't find agent'", resp.Message) } } @@ -610,7 +610,7 @@ func TestAgentbotInputs_MissingBeginComponent(t *testing.T) { func TestAgentbotInputs_NotFound(t *testing.T) { stub := &stubBotService{ agentbotInputsFn: func(ctx context.Context, tenantID, agentID string) (string, string, string, string, map[string]any, common.ErrorCode, error) { - return "", "", "", "", nil, common.CodeDataError, errors.New("Can't find agent by ID: a1") + return "", "", "", "", nil, common.CodeDataError, errors.New("can't find agent by ID: a1") }, } r := botTestEngine(stub) @@ -623,8 +623,8 @@ func TestAgentbotInputs_NotFound(t *testing.T) { if resp.Code != 102 { t.Errorf("code = %d, want 102", resp.Code) } - if !strings.Contains(resp.Message, "Can't find agent") { - t.Errorf("message = %q, want contains 'Can't find agent'", resp.Message) + if !strings.Contains(resp.Message, "can't find agent") { + t.Errorf("message = %q, want contains 'can't find agent'", resp.Message) } } @@ -1049,14 +1049,15 @@ func TestDownloadAttachment_Unauth(t *testing.T) { c.Abort() return } - if u, code, err := stub.GetUserByToken(c.Request.Context(), auth); err != nil || code != common.CodeSuccess { + u, code, err := stub.GetUserByToken(c.Request.Context(), auth) + if err != nil || code != common.CodeSuccess { common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "Invalid auth credentials") c.Abort() return - } else { - c.Set("user", u) - c.Next() } + + c.Set("user", u) + c.Next() }) g.GET("/attachments/:attachment_id/download", h.DownloadAttachment) @@ -1321,7 +1322,7 @@ func TestGetAgentbotLogs_DeniesInaccessibleAgent(t *testing.T) { h := NewBotHandler(nil) h.botService = &stubBotService{agentbotLogsFn: func(context.Context, string, string, string) (map[string]any, common.ErrorCode, error) { - return nil, common.CodeDataError, errors.New("Can't find agent by ID: agent-b") + return nil, common.CodeDataError, errors.New("can't find agent by ID: agent-b") }} h.GetAgentbotLogs(c) @@ -1333,7 +1334,7 @@ func TestGetAgentbotLogs_DeniesInaccessibleAgent(t *testing.T) { if resp.Code != int(common.CodeDataError) { t.Errorf("code = %d, want %d", resp.Code, common.CodeDataError) } - if !strings.Contains(resp.Message, "Can't find agent") { + if !strings.Contains(resp.Message, "can't find agent") { t.Errorf("message = %q, want an access denial", resp.Message) } } diff --git a/internal/handler/chat_session.go b/internal/handler/chat_session.go index bf56ce0bce..9a31718154 100644 --- a/internal/handler/chat_session.go +++ b/internal/handler/chat_session.go @@ -105,9 +105,9 @@ func (h *ChatSessionHandler) ListChatSessions(c *gin.Context) { ctx := c.Request.Context() result, err := h.chatSessionService.ListChatSessions(ctx, userID, chatID, c.Query("id"), c.Query("name"), orderby, desc, page, pageSize) if err != nil { - // Mirror Python: ownership failures return code 109 "No authorization." - if strings.Contains(err.Error(), "No authorization") { - common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "No authorization.") + // Mirror Python: ownership failures return code 109 "no authorization" + if strings.Contains(err.Error(), "no authorization") { + common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "no authorization") return } common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) diff --git a/internal/handler/dataset_artifact.go b/internal/handler/dataset_artifact.go index 5f65d4f3fa..1c898f6469 100644 --- a/internal/handler/dataset_artifact.go +++ b/internal/handler/dataset_artifact.go @@ -76,7 +76,7 @@ func (h *DatasetArtifactHandler) datasetOwner(c *gin.Context, datasetID string) return user, kb.TenantID, msg } -// HEAD /artifacts — any wiki artifact present? +// AnyArtifact handles HEAD /artifacts — any wiki artifact present? func (h *DatasetArtifactHandler) AnyArtifact(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -94,7 +94,7 @@ func (h *DatasetArtifactHandler) AnyArtifact(c *gin.Context) { } } -// GET /artifacts — list wiki pages. +// ListArtifacts handles GET /artifacts — list wiki pages. func (h *DatasetArtifactHandler) ListArtifacts(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -122,7 +122,7 @@ func (h *DatasetArtifactHandler) ListArtifacts(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "pages": items}, "success") } -// PUT /artifacts// — edit a wiki page. +// UpdateArtifact handles PUT /artifacts// — edit a wiki page. func (h *DatasetArtifactHandler) UpdateArtifact(c *gin.Context) { user, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -192,7 +192,7 @@ func (h *DatasetArtifactHandler) UpdateArtifact(c *gin.Context) { common.SuccessWithData(c, detail, "success") } -// GET /artifacts// — single wiki page. +// GetArtifact handles GET /artifacts// — single wiki page. func (h *DatasetArtifactHandler) GetArtifact(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -213,7 +213,7 @@ func (h *DatasetArtifactHandler) GetArtifact(c *gin.Context) { common.SuccessWithData(c, detail, "success") } -// DELETE /artifacts — clear all wiki artifacts. +// DeleteArtifacts handles DELETE /artifacts — clear all wiki artifacts. func (h *DatasetArtifactHandler) DeleteArtifacts(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -227,7 +227,7 @@ func (h *DatasetArtifactHandler) DeleteArtifacts(c *gin.Context) { common.SuccessWithData(c, deleted, "success") } -// GET /artifacts/topics — list wiki topics. +// ListArtifactTopics handles GET /artifacts/topics — list wiki topics. func (h *DatasetArtifactHandler) ListArtifactTopics(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -242,7 +242,7 @@ func (h *DatasetArtifactHandler) ListArtifactTopics(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "topics": items}, "success") } -// GET /artifacts/alteration — wiki alteration summary. +// GetArtifactAlteration handles GET /artifacts/alteration — wiki alteration summary. func (h *DatasetArtifactHandler) GetArtifactAlteration(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -257,7 +257,7 @@ func (h *DatasetArtifactHandler) GetArtifactAlteration(c *gin.Context) { common.SuccessWithData(c, alt, "success") } -// GET /artifacts/graph — wiki entity/relation graph. +// GetArtifactGraph handles GET /artifacts/graph — wiki entity/relation graph. func (h *DatasetArtifactHandler) GetArtifactGraph(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -272,7 +272,7 @@ func (h *DatasetArtifactHandler) GetArtifactGraph(c *gin.Context) { common.SuccessWithData(c, graph, "success") } -// GET /artifacts/structure — list compiled structures of a dataset. +// ListStructures handles GET /artifacts/structure — list compiled structures of a dataset. func (h *DatasetArtifactHandler) ListStructures(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -289,7 +289,7 @@ func (h *DatasetArtifactHandler) ListStructures(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "structures": items}, "success") } -// DELETE /artifacts/structure — delete compiled structures of a dataset. +// DeleteStructures handles DELETE /artifacts/structure — delete compiled structures of a dataset. func (h *DatasetArtifactHandler) DeleteStructures(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -306,7 +306,7 @@ func (h *DatasetArtifactHandler) DeleteStructures(c *gin.Context) { common.SuccessWithData(c, gin.H{"deleted": n}, "success") } -// HEAD /skills — any skill artifact present? +// AnySkill handles HEAD /skills — any skill artifact present? func (h *DatasetArtifactHandler) AnySkill(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -324,7 +324,7 @@ func (h *DatasetArtifactHandler) AnySkill(c *gin.Context) { } } -// GET /navigation — list navigation clusters. +// ListNavigation handles GET /navigation — list navigation clusters. func (h *DatasetArtifactHandler) ListNavigation(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -338,7 +338,7 @@ func (h *DatasetArtifactHandler) ListNavigation(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "nav": items}, "success") } -// DELETE /navigation — delete all navigation clusters. +// DeleteNavigation handles DELETE /navigation — delete all navigation clusters. func (h *DatasetArtifactHandler) DeleteNavigation(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -352,7 +352,7 @@ func (h *DatasetArtifactHandler) DeleteNavigation(c *gin.Context) { common.SuccessWithData(c, gin.H{"deleted": n}, "success") } -// DELETE /navigation/ — delete a single navigation cluster. +// DeleteNavigationNode handles DELETE /navigation/ — delete a single navigation cluster. func (h *DatasetArtifactHandler) DeleteNavigationNode(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -366,7 +366,7 @@ func (h *DatasetArtifactHandler) DeleteNavigationNode(c *gin.Context) { common.SuccessWithData(c, gin.H{"deleted": n}, "success") } -// GET /navigation//children — list children of a navigation cluster. +// ListNavigationChildren handles GET /navigation//children — list children of a navigation cluster. func (h *DatasetArtifactHandler) ListNavigationChildren(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -380,7 +380,7 @@ func (h *DatasetArtifactHandler) ListNavigationChildren(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "children": items}, "success") } -// GET /skills — skill tree. +// GetSkillTree handles GET /skills — skill tree. func (h *DatasetArtifactHandler) GetSkillTree(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -395,7 +395,7 @@ func (h *DatasetArtifactHandler) GetSkillTree(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "tree": items}, "success") } -// DELETE /skills — delete all skills. +// DeleteSkills handles DELETE /skills — delete all skills. func (h *DatasetArtifactHandler) DeleteSkills(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -409,7 +409,7 @@ func (h *DatasetArtifactHandler) DeleteSkills(c *gin.Context) { common.SuccessWithData(c, gin.H{"deleted": n}, "success") } -// GET /skills/ — single skill page. +// GetSkillPage handles GET /skills/ — single skill page. func (h *DatasetArtifactHandler) GetSkillPage(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -427,7 +427,7 @@ func (h *DatasetArtifactHandler) GetSkillPage(c *gin.Context) { common.SuccessWithData(c, detail, "success") } -// DELETE /skills/ — delete a single skill. +// DeleteSkill handles DELETE /skills/ — delete a single skill. func (h *DatasetArtifactHandler) DeleteSkill(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -441,7 +441,7 @@ func (h *DatasetArtifactHandler) DeleteSkill(c *gin.Context) { common.SuccessWithData(c, gin.H{"deleted": n}, "success") } -// GET /documents//structure/graph — document structure graph. +// GetDocumentGraph handles GET /documents//structure/graph — document structure graph. func (h *DatasetArtifactHandler) GetDocumentGraph(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { @@ -458,7 +458,7 @@ func (h *DatasetArtifactHandler) GetDocumentGraph(c *gin.Context) { common.SuccessWithData(c, gin.H{"total": total, "graph": items}, "success") } -// DELETE /documents//structure/graph — delete document structure graph. +// DeleteDocumentGraph handles DELETE /documents//structure/graph — delete document structure graph. func (h *DatasetArtifactHandler) DeleteDocumentGraph(c *gin.Context) { _, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id")) if tenantID == "" { diff --git a/internal/handler/document.go b/internal/handler/document.go index b94797da60..3847b97f25 100644 --- a/internal/handler/document.go +++ b/internal/handler/document.go @@ -263,7 +263,7 @@ func (h *DocumentHandler) GetDocumentPreview(c *gin.Context) { ctx := c.Request.Context() preview, err := h.documentService.GetDocumentPreview(ctx, docID) if err != nil { - common.ErrorWithCode(c, common.CodeDataError, "Document not found!") + common.ErrorWithCode(c, common.CodeDataError, "document not found") return } @@ -636,7 +636,7 @@ func parseDocumentListOptions(c *gin.Context, datasetID string) (dao.DocumentLis docID := c.Query("id") docIDs := queryValues(c, "ids") if docID != "" && len(docIDs) > 0 { - return opts, fmt.Sprintf("Should not provide both 'id':%s and 'ids'%v", docID, docIDs) + return opts, fmt.Sprintf("should not provide both 'id':%s and 'ids'%v", docID, docIDs) } if docID != "" { opts.DocIDs = []string{docID} diff --git a/internal/handler/openai_chat.go b/internal/handler/openai_chat.go index 626d65d310..9685a01652 100644 --- a/internal/handler/openai_chat.go +++ b/internal/handler/openai_chat.go @@ -92,7 +92,7 @@ func (h *OpenAIChatHandler) OpenAIChatCompletions(c *gin.Context) { return } else { for _, item := range rawArr { - if _, ok := item.(string); !ok { + if _, ok = item.(string); !ok { common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "reference_metadata.fields must be an array.") return diff --git a/internal/handler/search.go b/internal/handler/search.go index 5477c54d41..df4c371cbb 100644 --- a/internal/handler/search.go +++ b/internal/handler/search.go @@ -334,7 +334,7 @@ func (h *SearchHandler) UpdateSearch(c *gin.Context) { errMsg := err.Error() switch errMsg { case "no authorization": - common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "no authorization") case "duplicated search name": common.ResponseWithCodeData(c, common.CodeDataError, nil, "Duplicated search name.") default: diff --git a/internal/harness/core/event_sender.go b/internal/harness/core/event_sender.go index 04b6d35efd..0ea4b77877 100644 --- a/internal/harness/core/event_sender.go +++ b/internal/harness/core/event_sender.go @@ -6,7 +6,7 @@ import ( "ragflow/internal/harness/core/schema" ) -// ---- NewEventSenderModelWrapper creates a handler that sends model output events. +// NewEventSenderModelWrapper creates a handler that sends model output events. // Place this in the Handlers chain to control WHERE events are emitted: // - Innermost position (last in Handlers list): events contain original (unmodified) model output // - Outermost position (first in Handlers list): events contain fully processed output diff --git a/internal/harness/core/retry_test.go b/internal/harness/core/retry_test.go index 6914ff5dc0..8508a0407d 100644 --- a/internal/harness/core/retry_test.go +++ b/internal/harness/core/retry_test.go @@ -97,7 +97,7 @@ func TestWithModelRetry_Exhausted(t *testing.T) { func TestRetryExhaustedError_Unwrap(t *testing.T) { e := &RetryExhaustedError{LastErr: errors.New("boom"), TotalRetries: 3} - if errors.Unwrap(e) != ErrExceedMaxRetries { + if !errors.Is(errors.Unwrap(e), ErrExceedMaxRetries) { t.Error("Unwrap should return ErrExceedMaxRetries") } if e.Error() == "" { diff --git a/internal/harness/graph/checkpoint/nats.go b/internal/harness/graph/checkpoint/nats.go index d5b943b844..1f43d88a93 100644 --- a/internal/harness/graph/checkpoint/nats.go +++ b/internal/harness/graph/checkpoint/nats.go @@ -3,6 +3,7 @@ package checkpoint import ( "context" "encoding/json" + "errors" "fmt" "sync" "time" @@ -175,7 +176,7 @@ func (s *NATSSaver) Get(ctx context.Context, config map[string]interface{}) (map entry, err := s.kv.Get(ctx, key) if err != nil { - if err == jetstream.ErrKeyNotFound { + if errors.Is(err, jetstream.ErrKeyNotFound) { return nil, nil } return nil, fmt.Errorf("nats kv get %q: %w", key, err) diff --git a/internal/harness/graph/errors/errors_test.go b/internal/harness/graph/errors/errors_test.go index 338e8cdb9e..122843653c 100644 --- a/internal/harness/graph/errors/errors_test.go +++ b/internal/harness/graph/errors/errors_test.go @@ -2,6 +2,7 @@ package errors import ( + "errors" "testing" ) @@ -199,13 +200,13 @@ func TestChainError(t *testing.T) { // Test with nil base nilChained := ChainError(nil, newErr) - if nilChained != newErr { + if !errors.Is(nilChained, newErr) { t.Error("Chaining nil base should return new error") } // Test with nil new nilChained2 := ChainError(baseErr, nil) - if nilChained2 != baseErr { + if !errors.Is(nilChained2, baseErr) { t.Error("Chaining nil new should return base error") } } diff --git a/internal/harness/graph/managed/managed.go b/internal/harness/graph/managed/managed.go index c4ed8fe8f4..fdefd0f5dc 100644 --- a/internal/harness/graph/managed/managed.go +++ b/internal/harness/graph/managed/managed.go @@ -679,18 +679,6 @@ var DEFAULT_RUNTIME = &Runtime{ Previous: nil, } -// get_runtime returns the runtime for the current graph run. -// This corresponds to Python's get_runtime() function in runtime.py -func get_runtime(config map[string]interface{}) *Runtime { - if config == nil { - return DEFAULT_RUNTIME.Clone() - } - if runtime, ok := config[ManagedConfigKeyRuntime].(*Runtime); ok { - return runtime - } - return DEFAULT_RUNTIME.Clone() -} - // GetTaskID returns the task ID from config. func GetTaskID(config map[string]interface{}) string { if config == nil { @@ -962,7 +950,7 @@ func FormatDuration(d int64) string { return fmt.Sprintf("%.1fs", float64(d)/1000) } else if d < 3600000 { return fmt.Sprintf("%.1fm", float64(d)/60000) - } else { - return fmt.Sprintf("%.1fh", float64(d)/3600000) } + + return fmt.Sprintf("%.1fh", float64(d)/3600000) } diff --git a/internal/harness/graph/pregel/pregel_durability_timetravel_test.go b/internal/harness/graph/pregel/pregel_durability_timetravel_test.go index 301d5cc05a..40df8ab635 100644 --- a/internal/harness/graph/pregel/pregel_durability_timetravel_test.go +++ b/internal/harness/graph/pregel/pregel_durability_timetravel_test.go @@ -4,6 +4,7 @@ package pregel import ( "context" + "errors" "fmt" "sync" "sync/atomic" @@ -475,7 +476,7 @@ func TestFaultInjection_RapidCancel_Restart(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) _, err := engine.RunSync(ctx, map[string]any{"value": "cancel"}) cancel() - if err != nil && err != context.DeadlineExceeded && err != context.Canceled { + if err != nil && !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) { t.Logf("iteration %d: %v", i, err) } } diff --git a/internal/harness/graph/pregel/pregel_fault_edge_test.go b/internal/harness/graph/pregel/pregel_fault_edge_test.go index 693c5be403..4f2ea31fc8 100644 --- a/internal/harness/graph/pregel/pregel_fault_edge_test.go +++ b/internal/harness/graph/pregel/pregel_fault_edge_test.go @@ -3,6 +3,7 @@ package pregel import ( "context" + "errors" "fmt" "sync" "sync/atomic" @@ -272,7 +273,7 @@ func TestFault_ContextCancelledBeforeRun(t *testing.T) { cancel() // cancel immediately _, err := engine.RunSync(ctx, map[string]any{"value": "x"}) - if err != nil && err != context.Canceled { + if err != nil && !errors.Is(err, context.Canceled) { t.Logf("expected cancellation: %v", err) } } diff --git a/internal/harness/graph/pregel/pregel_fault_injection_test.go b/internal/harness/graph/pregel/pregel_fault_injection_test.go index 87ea2a434b..52c7f1482d 100644 --- a/internal/harness/graph/pregel/pregel_fault_injection_test.go +++ b/internal/harness/graph/pregel/pregel_fault_injection_test.go @@ -7,6 +7,7 @@ package pregel import ( "context" + "errors" "fmt" "sync" "sync/atomic" @@ -271,7 +272,7 @@ func TestFaultInjection_ContextCancel(t *testing.T) { for range outputCh { } err := <-errCh - if err != nil && err != context.Canceled { + if err != nil && !errors.Is(err, context.Canceled) { t.Fatalf("expected context.Canceled or nil, got: %v", err) } } diff --git a/internal/harness/graph/pregel/pregel_pressure_test.go b/internal/harness/graph/pregel/pregel_pressure_test.go index 7d8f424a9e..413443b43e 100644 --- a/internal/harness/graph/pregel/pregel_pressure_test.go +++ b/internal/harness/graph/pregel/pregel_pressure_test.go @@ -1154,9 +1154,9 @@ func TestEngine_MaxIterationsVsConditionStable(t *testing.T) { _, err := engine.RunSync(context.Background(), map[string]any{}) if err == nil { t.Skip("engine completed without limit enforcement (timing)") - } else { - t.Logf("recursion limit correctly enforced for unstable loop: %v", err) } + + t.Logf("recursion limit correctly enforced for unstable loop: %v", err) }) t.Run("condition_stable_terminates_normally", func(t *testing.T) { @@ -1449,9 +1449,9 @@ func TestEngine_ExtremeConfigValues(t *testing.T) { _, err := engine.RunSync(context.Background(), map[string]any{}) if err == nil { t.Skip("engine didn't enforce recursion limit 0 (allowed step 0)") - } else { - t.Logf("recursion limit 0 correctly enforced: %v", err) } + + t.Logf("recursion limit 0 correctly enforced: %v", err) }) t.Run("recursion_limit_one", func(t *testing.T) { diff --git a/internal/harness/graph/task/decorator_test.go b/internal/harness/graph/task/decorator_test.go index 0025b7e43a..b3b37c9522 100644 --- a/internal/harness/graph/task/decorator_test.go +++ b/internal/harness/graph/task/decorator_test.go @@ -173,7 +173,7 @@ func TestWithTimeout(t *testing.T) { if err == nil { t.Error("expected timeout error") } - if err != context.DeadlineExceeded { + if !errors.Is(err, context.DeadlineExceeded) { t.Errorf("expected DeadlineExceeded, got %v", err) } } diff --git a/internal/ingestion/component/chunker/group.go b/internal/ingestion/component/chunker/group.go index fe263c6119..51ba9d4691 100644 --- a/internal/ingestion/component/chunker/group.go +++ b/internal/ingestion/component/chunker/group.go @@ -14,6 +14,7 @@ // limitations under the License. // +// Package chunker implements the GroupTitleChunker variant: aggregates adjacent // SCOPE (honest) for group.go: // // - Implements the GroupTitleChunker variant: aggregates adjacent diff --git a/internal/ingestion/component/dispatch_model.go b/internal/ingestion/component/dispatch_model.go index b6c74a4e76..5be97e186c 100644 --- a/internal/ingestion/component/dispatch_model.go +++ b/internal/ingestion/component/dispatch_model.go @@ -22,6 +22,7 @@ package component import ( "context" "encoding/json" + "errors" "fmt" "strings" @@ -297,5 +298,5 @@ func newModelDriverForBaseURLLocal(driver modelModule.ModelDriver, providerName, } func errorsIsRecordNotFound(err error) bool { - return err != nil && (err == gorm.ErrRecordNotFound || strings.Contains(err.Error(), gorm.ErrRecordNotFound.Error())) + return err != nil && (errors.Is(err, gorm.ErrRecordNotFound) || strings.Contains(err.Error(), gorm.ErrRecordNotFound.Error())) } diff --git a/internal/ingestion/component/file.go b/internal/ingestion/component/file.go index f6a803a3fc..fe88499010 100644 --- a/internal/ingestion/component/file.go +++ b/internal/ingestion/component/file.go @@ -14,7 +14,7 @@ // limitations under the License. // -// File ingestion component (Phase 2.1) — port of python `rag/flow/file.py`. +// Package component implements File ingestion component (Phase 2.1) — port of python `rag/flow/file.py`. // // SCOPE (honest): // diff --git a/internal/ingestion/component/parser.go b/internal/ingestion/component/parser.go index 9fef42ab57..8155c2f028 100644 --- a/internal/ingestion/component/parser.go +++ b/internal/ingestion/component/parser.go @@ -171,7 +171,7 @@ func NewParserComponent(params map[string]any) (runtime.Component, error) { } pc := &ParserComponent{Setups: s, Param: p} if err := pc.Check(); err != nil { - return nil, fmt.Errorf("Parser: %w", err) + return nil, fmt.Errorf("parser: %w", err) } return pc, nil } @@ -195,7 +195,7 @@ func (c *ParserComponent) Check() error { if pdf, ok := c.Setups["pdf"]; ok { pm, _ := pdf["parse_method"].(string) if pm == "" { - return errors.New("Parse method abnormal. does not support empty value.") + return errors.New("parse method abnormal. does not support empty value") } pmLower := strings.ToLower(pm) pdfWhitelist := []string{ @@ -206,7 +206,7 @@ func (c *ParserComponent) Check() error { // Non-whitelist parse_method is treated as a VLM method, // which requires lang (Python parser.py:257-258). if lang, _ := pdf["lang"].(string); lang == "" { - return errors.New("PDF VLM language does not support empty value.") + return errors.New("PDF VLM language does not support empty value") } } } @@ -216,7 +216,7 @@ func (c *ParserComponent) Check() error { // OCR mode does not need a VLM language; any other value does. if pm != "ocr" { if lang, _ := img["lang"].(string); lang == "" { - return errors.New("Image VLM language does not support empty value.") + return errors.New("image VLM language does not support empty value") } } } diff --git a/internal/ingestion/component/parser_check_test.go b/internal/ingestion/component/parser_check_test.go index 47c134483f..c205ccd9ca 100644 --- a/internal/ingestion/component/parser_check_test.go +++ b/internal/ingestion/component/parser_check_test.go @@ -40,12 +40,12 @@ func TestParserComponent_Check(t *testing.T) { { name: "pdf: parse_method empty → error", setups: map[string]schema.ParserSetup{"pdf": {"parse_method": ""}}, - wantErr: "Parse method abnormal", + wantErr: "parse method abnormal", }, { name: "pdf: parse_method missing → error", setups: map[string]schema.ParserSetup{"pdf": {}}, - wantErr: "Parse method abnormal", + wantErr: "parse method abnormal", }, { name: "pdf: deepdoc (whitelist) without lang → pass", @@ -85,7 +85,7 @@ func TestParserComponent_Check(t *testing.T) { { name: "image: non-ocr without lang → error", setups: map[string]schema.ParserSetup{"image": {"parse_method": "vlm_xyz", "lang": ""}}, - wantErr: "Image VLM language", + wantErr: "image VLM language", }, { name: "image: non-ocr with lang → pass", @@ -165,8 +165,8 @@ func TestParserComponent_New_RunsCheck(t *testing.T) { if err == nil { t.Fatal("NewParserComponent with empty pdf.parse_method: want error, got nil") } - if !strings.Contains(err.Error(), "Parse method abnormal") { - t.Errorf("error = %q, want substring %q", err.Error(), "Parse method abnormal") + if !strings.Contains(err.Error(), "parse method abnormal") { + t.Errorf("error = %q, want substring %q", err.Error(), "parse method abnormal") } if c != nil { t.Errorf("want nil component on error, got %T", c) diff --git a/internal/ingestion/component/parser_dispatch.go b/internal/ingestion/component/parser_dispatch.go index 05b9f5b042..f69ce9637f 100644 --- a/internal/ingestion/component/parser_dispatch.go +++ b/internal/ingestion/component/parser_dispatch.go @@ -118,7 +118,7 @@ func resolveOutputFormat(family string, setups map[string]schema.ParserSetup, al } } return "", fmt.Errorf( - "Parser: output_format %q for %q is not in allowed_output_format %v", + "parser: output_format %q for %q is not in allowed_output_format %v", format, family, allowedList, ) } @@ -156,13 +156,13 @@ func dispatchParse(ctx context.Context, fileType utility.FileType, filename stri p, err := parser.GetParser(fileType) if err != nil { - return parserDispatchResult{Err: fmt.Errorf("Parser: resolve %q: %w", fileType, err)} + return parserDispatchResult{Err: fmt.Errorf("parser: resolve %q: %w", fileType, err)} } configureParserFromSetups(p, fileType, setups) res := p.ParseWithResult(ctx, filename, data) if res.Err != nil { - return parserDispatchResult{Err: fmt.Errorf("Parser: %q: %w", fileType, res.Err)} + return parserDispatchResult{Err: fmt.Errorf("parser: %q: %w", fileType, res.Err)} } // Carry the configured parse_method on the file metadata so // downstream consumers can read which provider ran. diff --git a/internal/ingestion/component/tokenizer.go b/internal/ingestion/component/tokenizer.go index 007d4a3d52..db9c030eb6 100644 --- a/internal/ingestion/component/tokenizer.go +++ b/internal/ingestion/component/tokenizer.go @@ -244,7 +244,7 @@ func newTokenizerComponent(params map[string]any, resolver EmbedderResolver) (ru embeddingModel = embeddingModelFromSetups(params) } if err := p.Validate(); err != nil { - return nil, fmt.Errorf("Tokenizer: param check: %w", err) + return nil, fmt.Errorf("tokenizer: param check: %w", err) } return &TokenizerComponent{param: p, resolver: resolver, embeddingModel: embeddingModel}, nil } @@ -395,14 +395,14 @@ func (c *TokenizerComponent) embedChunks(ctx context.Context, tenantID, kbID, em resolver = DefaultEmbedderResolver } if resolver == nil { - return nil, 0, fmt.Errorf("Tokenizer: embedding requested but no embedder resolver configured") + return nil, 0, fmt.Errorf("tokenizer: embedding requested but no embedder resolver configured") } embedder, err := resolver(ctx, tenantID, kbID, embeddingModel) if err != nil { - return nil, 0, fmt.Errorf("Tokenizer: resolve embedder: %w", err) + return nil, 0, fmt.Errorf("tokenizer: resolve embedder: %w", err) } if embedder == nil { - return nil, 0, fmt.Errorf("Tokenizer: embedding requested but encoder resolution returned nil") + return nil, 0, fmt.Errorf("tokenizer: embedding requested but encoder resolution returned nil") } texts := make([]string, 0, len(chunks)) @@ -437,10 +437,10 @@ func (c *TokenizerComponent) embedChunks(ctx context.Context, tenantID, kbID, em // `.strip()==""` check at tokenizer.py:200. titleResults, err := embedder.Encode(ctx, []string{name}) if err != nil { - return nil, 0, fmt.Errorf("Tokenizer: encode title: %w", err) + return nil, 0, fmt.Errorf("tokenizer: encode title: %w", err) } if len(titleResults) != 1 { - return nil, 0, fmt.Errorf("Tokenizer: encode title returned %d vectors for 1 chunk", len(titleResults)) + return nil, 0, fmt.Errorf("tokenizer: encode title returned %d vectors for 1 chunk", len(titleResults)) } titleVec = titleResults[0].Vector tokenCount = titleResults[0].TokenCount @@ -455,10 +455,10 @@ func (c *TokenizerComponent) embedChunks(ctx context.Context, tenantID, kbID, em } batchResults, err := embedder.Encode(ctx, texts[start:end]) if err != nil { - return nil, 0, fmt.Errorf("Tokenizer: encode: %w", err) + return nil, 0, fmt.Errorf("tokenizer: encode: %w", err) } if len(batchResults) != end-start { - return nil, 0, fmt.Errorf("Tokenizer: encode returned %d vectors for %d chunks", len(batchResults), end-start) + return nil, 0, fmt.Errorf("tokenizer: encode returned %d vectors for %d chunks", len(batchResults), end-start) } for _, result := range batchResults { tokenCount += result.TokenCount @@ -472,11 +472,11 @@ func (c *TokenizerComponent) embedChunks(ctx context.Context, tenantID, kbID, em if hasTitleVec { merged, err = mergeEmbeddingVectors(titleVec, contentResults[i].Vector, titleWeight) if err != nil { - return nil, 0, fmt.Errorf("Tokenizer: merge vectors: %w", err) + return nil, 0, fmt.Errorf("tokenizer: merge vectors: %w", err) } } if err := chunks[idx].SetExtraValue(fmt.Sprintf("q_%d_vec", len(merged)), merged); err != nil { - return nil, 0, fmt.Errorf("Tokenizer: vector marshal: %w", err) + return nil, 0, fmt.Errorf("tokenizer: vector marshal: %w", err) } } return chunks, tokenCount, nil @@ -530,17 +530,17 @@ func mergeEmbeddingVectors(titleVec, contentVec []float64, titleWeight float64) func decodeTokenizerFromUpstream(inputs map[string]any) (schema.TokenizerFromUpstream, error) { var out schema.TokenizerFromUpstream if inputs == nil { - return out, fmt.Errorf("Tokenizer: inputs map is nil") + return out, fmt.Errorf("tokenizer: inputs map is nil") } data, err := json.Marshal(stripRuntimeTimestamps(inputs)) if err != nil { - return out, fmt.Errorf("Tokenizer: encode inputs: %w", err) + return out, fmt.Errorf("tokenizer: encode inputs: %w", err) } - if err := json.Unmarshal(data, &out); err != nil { - return out, fmt.Errorf("Tokenizer: decode inputs: %w", err) + if err = json.Unmarshal(data, &out); err != nil { + return out, fmt.Errorf("tokenizer: decode inputs: %w", err) } - if err := out.Validate(); err != nil { - return out, fmt.Errorf("Tokenizer: input error: %w", err) + if err = out.Validate(); err != nil { + return out, fmt.Errorf("tokenizer: input error: %w", err) } return out, nil } @@ -674,11 +674,11 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) ck.ChunkOrderInt = intPtr(i) titleTk, err := tok.Tokenize(titleStem) if err != nil { - return fmt.Errorf("Tokenizer: title tokenize: %w", err) + return fmt.Errorf("tokenizer: title tokenize: %w", err) } titleSmTk, err := tok.FineGrainedTokenize(titleTk) if err != nil { - return fmt.Errorf("Tokenizer: title fine-grain: %w", err) + return fmt.Errorf("tokenizer: title fine-grain: %w", err) } ck.TitleTks = titleTk ck.TitleSmTks = titleSmTk @@ -686,27 +686,27 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) // Question / keyword / summary fields are optional. The python // path branches on each independently. if q := ck.Questions; q != "" { - if err := ck.SetExtraValue("question_kwd", strings.Split(q, "\n")); err != nil { - return fmt.Errorf("Tokenizer: question keywords marshal: %w", err) + if err = ck.SetExtraValue("question_kwd", strings.Split(q, "\n")); err != nil { + return fmt.Errorf("tokenizer: question keywords marshal: %w", err) } qt, err := tok.Tokenize(q) if err != nil { - return fmt.Errorf("Tokenizer: question tokenize: %w", err) + return fmt.Errorf("tokenizer: question tokenize: %w", err) } - if err := ck.SetExtraValue("question_tks", qt); err != nil { - return fmt.Errorf("Tokenizer: question tokens marshal: %w", err) + if err = ck.SetExtraValue("question_tks", qt); err != nil { + return fmt.Errorf("tokenizer: question tokens marshal: %w", err) } } if kw := ck.Keywords; kw != "" { - if err := ck.SetExtraValue("important_kwd", utility.SplitKeywords(kw)); err != nil { - return fmt.Errorf("Tokenizer: keyword list marshal: %w", err) + if err = ck.SetExtraValue("important_kwd", utility.SplitKeywords(kw)); err != nil { + return fmt.Errorf("tokenizer: keyword list marshal: %w", err) } it, err := tok.Tokenize(kw) if err != nil { - return fmt.Errorf("Tokenizer: keyword tokenize: %w", err) + return fmt.Errorf("tokenizer: keyword tokenize: %w", err) } - if err := ck.SetExtraValue("important_tks", it); err != nil { - return fmt.Errorf("Tokenizer: keyword tokens marshal: %w", err) + if err = ck.SetExtraValue("important_tks", it); err != nil { + return fmt.Errorf("tokenizer: keyword tokens marshal: %w", err) } } // Keep Go: skip whitespace-only summaries so they don't shadow @@ -715,7 +715,7 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) if s := strings.TrimSpace(ck.Summary); s != "" { st, err := tok.Tokenize(s) if err != nil { - return fmt.Errorf("Tokenizer: summary tokenize: %w", err) + return fmt.Errorf("tokenizer: summary tokenize: %w", err) } if st == "" { st = s @@ -723,7 +723,7 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) ck.ContentLtks = st smt, err := tok.FineGrainedTokenize(st) if err != nil { - return fmt.Errorf("Tokenizer: summary fine-grain: %w", err) + return fmt.Errorf("tokenizer: summary fine-grain: %w", err) } if smt == "" { smt = st @@ -732,7 +732,7 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) } else if t := ck.Text; strings.TrimSpace(t) != "" { tt, err := tok.Tokenize(t) if err != nil { - return fmt.Errorf("Tokenizer: text tokenize: %w", err) + return fmt.Errorf("tokenizer: text tokenize: %w", err) } if tt == "" { tt = t @@ -740,7 +740,7 @@ func tokenizeChunks(chunks []schema.ChunkDoc, titleStem string, language string) ck.ContentLtks = tt smt, err := tok.FineGrainedTokenize(tt) if err != nil { - return fmt.Errorf("Tokenizer: text fine-grain: %w", err) + return fmt.Errorf("tokenizer: text fine-grain: %w", err) } if smt == "" { smt = tt @@ -796,12 +796,12 @@ func validateTokenizerOutputs(chunks []schema.ChunkDoc, searchMethods, fields [] for i := range chunks { if needFullText && requiresFullTextTokens(chunks[i]) { if strings.TrimSpace(chunks[i].ContentLtks) == "" || strings.TrimSpace(chunks[i].ContentSmLtks) == "" { - return fmt.Errorf("Tokenizer: chunk[%d] missing full_text tokens", i) + return fmt.Errorf("tokenizer: chunk[%d] missing full_text tokens", i) } } if needEmbedding && requiresEmbeddingVector(chunks[i], fields) { if !hasEmbeddingVector(chunks[i]) { - return fmt.Errorf("Tokenizer: chunk[%d] missing embedding vector", i) + return fmt.Errorf("tokenizer: chunk[%d] missing embedding vector", i) } } } diff --git a/internal/ingestion/pipeline/pipeline.go b/internal/ingestion/pipeline/pipeline.go index d30f05a882..9f8abfb804 100644 --- a/internal/ingestion/pipeline/pipeline.go +++ b/internal/ingestion/pipeline/pipeline.go @@ -54,7 +54,7 @@ type Pipeline struct { tracker *canvas.RunTracker // optional injected; nil -> resolve at Run // requireResume, when true, makes Run refuse to start if no checkpoint // store can be resolved (no injected store AND no global Redis client). - // Plan §6.a M4 方案 A: a deployment that cannot persist checkpoints must + // Plan §6.a M4: a deployment that cannot persist checkpoints must // not silently degrade to a non-resumable run — it must surface a clear, // distinguishable error so the caller knows resume is unavailable. requireResume bool @@ -387,7 +387,7 @@ func coalesceErr(errs ...error) error { // There is no pipeline-layer partial resume entry point: execution always // starts from the graph entry and component-level replay decisions belong to // the components themselves. -func (p *Pipeline) Run(ctx context.Context, inputs map[string]any, override_params map[string]any) (map[string]any, error) { +func (p *Pipeline) Run(ctx context.Context, inputs map[string]any, overrideParams map[string]any) (map[string]any, error) { if p == nil { return nil, fmt.Errorf("pipeline: Run on nil pipeline") } @@ -414,7 +414,7 @@ func (p *Pipeline) Run(ctx context.Context, inputs map[string]any, override_para store := p.resolveStore() tracker := p.resolveTracker() - // M4 (plan §6.a 方案 A): refuse to start when resume is required but no + // M4 (plan §6.a): refuse to start when resume is required but no // checkpoint store is resolvable. A Redis-less deployment must not pretend // the task is resumable; it must report the gap clearly so the caller can // refuse to enqueue the task instead of silently running a non-resumable @@ -435,8 +435,8 @@ func (p *Pipeline) Run(ctx context.Context, inputs map[string]any, override_para } // Run-level setups (keyed by cpnID) override the DSL-baked component // setups at compile time (higher priority; see canvas.WithOverrideParams). - if override_params != nil { - compileOpts = append(compileOpts, canvas.WithOverrideParams(override_params)) + if overrideParams != nil { + compileOpts = append(compileOpts, canvas.WithOverrideParams(overrideParams)) } compiled, err := canvas.Compile(compileCtx, p.canvas, compileOpts...) if err != nil { @@ -477,7 +477,7 @@ func (p *Pipeline) Run(ctx context.Context, inputs map[string]any, override_para // Resumable path: detect DSL / override edits since the checkpoint was // written and discard a stale checkpoint before resuming (see guardDSLChange). - p.guardDSLChange(ctx, store, tracker, p.taskID, override_params) + p.guardDSLChange(ctx, store, tracker, p.taskID, overrideParams) // Resumable path: record the run, then loop Invoke until the graph // completes or a non-resumable error surfaces. diff --git a/internal/ingestion/task/chunk_utils_test.go b/internal/ingestion/task/chunk_utils_test.go index 7f42bf14aa..0698f09171 100644 --- a/internal/ingestion/task/chunk_utils_test.go +++ b/internal/ingestion/task/chunk_utils_test.go @@ -199,8 +199,8 @@ func TestNormalizeChunks_DoesNotMutateInput(t *testing.T) { func TestNormalizeChunks_DeepCopyVectors(t *testing.T) { // Python: copy.deepcopy creates fully independent copies. // Mutating a slice element in the result must NOT affect the original. - original_vec := []float64{0.1, 0.2, 0.3} - original := []map[string]any{{"text": "hello", "q_3_vec": original_vec}} + originalVec := []float64{0.1, 0.2, 0.3} + original := []map[string]any{{"text": "hello", "q_3_vec": originalVec}} input := map[string]any{"chunks": original} result := NormalizeChunks(input) // Mutate the slice *element* in-place (not replace the slice) diff --git a/internal/ingestion/task/pipeline_real_integration_test.go b/internal/ingestion/task/pipeline_real_integration_test.go index 6e68d68e20..9c3068445d 100644 --- a/internal/ingestion/task/pipeline_real_integration_test.go +++ b/internal/ingestion/task/pipeline_real_integration_test.go @@ -422,7 +422,7 @@ func mustOpenTaskTestDB(t *testing.T) *gorm.DB { if err != nil { t.Fatalf("open in-memory sqlite db: %v", err) } - if err := db.AutoMigrate( + if err = db.AutoMigrate( &entity.Tenant{}, &entity.Knowledgebase{}, &entity.Document{}, @@ -433,11 +433,12 @@ func mustOpenTaskTestDB(t *testing.T) *gorm.DB { ); err != nil { t.Fatalf("auto-migrate sqlite tables: %v", err) } - if sqlDB, err := db.DB(); err != nil { + + sqlDB, err := db.DB() + if err != nil { t.Fatalf("get sql.DB from gorm: %v", err) - } else { - sqlDB.SetMaxOpenConns(1) } + sqlDB.SetMaxOpenConns(1) return db } diff --git a/internal/parser/chunk/execute.go b/internal/parser/chunk/execute.go index 58a40d2264..c879054633 100644 --- a/internal/parser/chunk/execute.go +++ b/internal/parser/chunk/execute.go @@ -14,13 +14,12 @@ // limitations under the License. // -// Internal chunk execution entrypoint used by production callers. package chunk import "fmt" // Run executes the internal chunk steps against `text` using typed -// options. The sequence is preprocess -> split -> postprocess. +// options. The sequence is pre-process -> split -> postprocess. func Run(text string, opts ChunkOptions) (*ChunkContext, error) { if err := opts.validate(); err != nil { return nil, err diff --git a/internal/service/agent_dbcheck.go b/internal/service/agent_dbcheck.go index a971c78a46..5389280c30 100644 --- a/internal/service/agent_dbcheck.go +++ b/internal/service/agent_dbcheck.go @@ -68,7 +68,7 @@ func allowAnyHost() bool { func AssertHostIsSafe(host string) (string, error) { host = strings.TrimSpace(host) if host == "" { - return "", errors.New("Host must not be empty.") + return "", errors.New("host must not be empty") } if allowAnyHost() { zap.L().Warn("SSRF guard bypass enabled via AllowAnyHostForTest; allowing host without validation", @@ -83,13 +83,13 @@ func AssertHostIsSafe(host string) (string, error) { zap.String("host", host), zap.Error(err), ) - return "", fmt.Errorf("Could not resolve host %q: %w", host, err) + return "", fmt.Errorf("could not resolve host %q: %w", host, err) } if len(ips) == 0 { zap.L().Warn("SSRF guard blocked host: resolved to no addresses", zap.String("host", host), ) - return "", fmt.Errorf("Host %q resolved to no addresses.", host) + return "", fmt.Errorf("host %q resolved to no addresses", host) } var resolvedIP string @@ -106,14 +106,14 @@ func AssertHostIsSafe(host string) (string, error) { zap.String("host", host), zap.String("resolved_ip", addr.String()), ) - return "", fmt.Errorf("Host resolves to a non-public address (%s), which is not allowed.", addr.String()) + return "", fmt.Errorf("host resolves to a non-public address (%s), which is not allowed", addr.String()) } if resolvedIP == "" { resolvedIP = addr.String() } } if resolvedIP == "" { - return "", fmt.Errorf("Host %q resolved to no addresses.", host) + return "", fmt.Errorf("host %q resolved to no addresses", host) } return resolvedIP, nil } @@ -256,7 +256,8 @@ func (s *AgentService) TestDBConnection(userID string, req *TestDBConnectionRequ Timeout: dbProbeTimeout, AllowNativePasswords: true, } - db, err := sql.Open("mysql", config.FormatDSN()) + var db *sql.DB + db, err = sql.Open("mysql", config.FormatDSN()) if err != nil { return common.CodeExceptionError, err } @@ -265,14 +266,14 @@ func (s *AgentService) TestDBConnection(userID string, req *TestDBConnectionRequ ctx, cancel := context.WithTimeout(context.Background(), dbProbeTimeout) defer cancel() - if err := db.PingContext(ctx); err != nil { + if err = db.PingContext(ctx); err != nil { return common.CodeExceptionError, err } - if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil { + if _, err = db.ExecContext(ctx, "SELECT 1"); err != nil { return common.CodeExceptionError, err } default: - return common.CodeExceptionError, errors.New("Unsupported database type.") + return common.CodeExceptionError, errors.New("unsupported database type") } return common.CodeSuccess, nil diff --git a/internal/service/agent_test.go b/internal/service/agent_test.go index c984777f8a..e0282fae07 100644 --- a/internal/service/agent_test.go +++ b/internal/service/agent_test.go @@ -1180,12 +1180,12 @@ func TestUpdateAgentTagsServiceSuccess(t *testing.T) { t.Fatal("expected update to succeed") } - canvas, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") + canvasInstance, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") if err != nil { t.Fatalf("failed to get canvas: %v", err) } - if canvas.Tags != "alpha,beta,with comma" { - t.Fatalf("expected normalized tags, got %q", canvas.Tags) + if canvasInstance.Tags != "alpha,beta,with comma" { + t.Fatalf("expected normalized tags, got %q", canvasInstance.Tags) } } @@ -1206,12 +1206,12 @@ func TestUpdateAgentTagsServiceInvalidPayload(t *testing.T) { t.Fatal("expected update to fail") } - canvas, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") + canvasInstance, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") if err != nil { t.Fatalf("failed to get canvas: %v", err) } - if canvas.Tags != "" { - t.Fatalf("expected tags to remain unchanged, got %q", canvas.Tags) + if canvasInstance.Tags != "" { + t.Fatalf("expected tags to remain unchanged, got %q", canvasInstance.Tags) } } @@ -1232,12 +1232,12 @@ func TestUpdateAgentTagsServiceNoPermission(t *testing.T) { t.Fatal("expected update to fail") } - canvas, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") + canvasInstance, err := dao.NewUserCanvasDAO().GetByID(ctx, dao.DB, "canvas-1") if err != nil { t.Fatalf("failed to get canvas: %v", err) } - if canvas.Tags != "" { - t.Fatalf("expected tags to remain unchanged, got %q", canvas.Tags) + if canvasInstance.Tags != "" { + t.Fatalf("expected tags to remain unchanged, got %q", canvasInstance.Tags) } } @@ -1305,7 +1305,7 @@ func TestTestDBConnectionUnsupportedDatabaseType(t *testing.T) { if code != common.CodeExceptionError { t.Fatalf("expected code %d, got %d", common.CodeExceptionError, code) } - if err.Error() != "Unsupported database type." { + if err.Error() != "unsupported database type" { t.Fatalf("unexpected error: %v", err) } } diff --git a/internal/service/bot.go b/internal/service/bot.go index edefe521c5..e1bbaf6452 100644 --- a/internal/service/bot.go +++ b/internal/service/bot.go @@ -92,7 +92,7 @@ func (s *BotService) ChatbotInfo(ctx context.Context, tenantID, dialogID string) if dialog == nil || dialog.TenantID != tenantID || dialog.Status == nil || *dialog.Status != common.StatusDialogValid { return "", "", "", "", false, common.CodeDataError, - errors.New("Authentication error: no access to this chatbot!") + errors.New("authentication error: no access to this chatbot") } pc := dialog.PromptConfig // Defensive lookups mirroring python's diff --git a/internal/service/chat_pipeline_test.go b/internal/service/chat_pipeline_test.go index 8338eb9993..0b23341e9c 100644 --- a/internal/service/chat_pipeline_test.go +++ b/internal/service/chat_pipeline_test.go @@ -1186,10 +1186,10 @@ func (f *sqlFakeEngine) RunSQL(ctx context.Context, table, sqlText string, kbIDs // Infinity multi-KB short-circuit (mirrors Python's add_kb_filter // no-op for Infinity). func TestFetchAggregateChunks_SkipsInfinityMultiKB(t *testing.T) { - engine := &sqlFakeEngine{engineType: "infinity"} + sqlEngine := &sqlFakeEngine{engineType: "infinity"} s := &ChatPipelineService{} chunks, docAggs := s.fetchAggregateChunks( - context.Background(), engine, "t", + context.Background(), sqlEngine, "t", "select count(*) from t where x = 1", "docnm", []string{"kb_a", "kb_b"}, ) @@ -1202,7 +1202,7 @@ func TestFetchAggregateChunks_SkipsInfinityMultiKB(t *testing.T) { // path populates chunks and doc_aggs correctly. func TestFetchAggregateChunks_SingleKBSuccess(t *testing.T) { chunksSQL := "select doc_id, docnm_kwd from t where x = 1 limit 20" - engine := &sqlFakeEngine{ + sqlEngine := &sqlFakeEngine{ engineType: "elasticsearch", rowsBySQL: map[string][]map[string]interface{}{ chunksSQL: { @@ -1214,7 +1214,7 @@ func TestFetchAggregateChunks_SingleKBSuccess(t *testing.T) { } s := &ChatPipelineService{} chunks, docAggs := s.fetchAggregateChunks( - context.Background(), engine, "t", + context.Background(), sqlEngine, "t", "select count(*) from t where x = 1", "docnm_kwd", []string{"kb_a"}, ) @@ -1243,10 +1243,10 @@ func TestFetchAggregateChunks_SingleKBSuccess(t *testing.T) { // TestFetchAggregateChunks_NoWhereClause verifies the no-WHERE early // return (matches Python's aggregate fallback at L1365). func TestFetchAggregateChunks_NoWhereClause(t *testing.T) { - engine := &sqlFakeEngine{engineType: "elasticsearch"} + sqlEngine := &sqlFakeEngine{engineType: "elasticsearch"} s := &ChatPipelineService{} chunks, docAggs := s.fetchAggregateChunks( - context.Background(), engine, "t", + context.Background(), sqlEngine, "t", "select count(*) from t", "docnm_kwd", []string{"kb_a"}, ) @@ -1257,7 +1257,7 @@ func TestFetchAggregateChunks_NoWhereClause(t *testing.T) { // TestFetchAggregateChunks_RunSQLError verifies graceful failure. func TestFetchAggregateChunks_RunSQLError(t *testing.T) { - engine := &sqlFakeEngine{ + sqlEngine := &sqlFakeEngine{ engineType: "elasticsearch", runSQL: func(ctx context.Context, table, sqlText string, kbIDs []string) ([]map[string]interface{}, error) { return nil, fmt.Errorf("engine boom") @@ -1265,7 +1265,7 @@ func TestFetchAggregateChunks_RunSQLError(t *testing.T) { } s := &ChatPipelineService{} chunks, docAggs := s.fetchAggregateChunks( - context.Background(), engine, "t", + context.Background(), sqlEngine, "t", "select count(*) from t where x = 1", "docnm_kwd", []string{"kb_a"}, ) @@ -1336,7 +1336,7 @@ func TestBuildSQLReference_AggregateMissingSourceColumnsSecondaryFetch(t *testin {"count": 42.0, "label": "total"}, } chunksSQL := "select doc_id, docnm_kwd from t where x = 1 limit 20" - engine := &sqlFakeEngine{ + sqlEngine := &sqlFakeEngine{ engineType: "elasticsearch", rowsBySQL: map[string][]map[string]interface{}{ chunksSQL: { @@ -1347,7 +1347,7 @@ func TestBuildSQLReference_AggregateMissingSourceColumnsSecondaryFetch(t *testin kbs := []*entity.Knowledgebase{{ID: "kb_a"}} s := &ChatPipelineService{} ans, ref := s.buildSQLReference( - context.Background(), engine, "t", + context.Background(), sqlEngine, "t", "select count(*) from t where x = 1", rows, "", "elasticsearch", kbs, nil, ) diff --git a/internal/service/chat_session.go b/internal/service/chat_session.go index f331659371..8151af67a3 100644 --- a/internal/service/chat_session.go +++ b/internal/service/chat_session.go @@ -275,7 +275,7 @@ func (s *ChatSessionService) ListChatSessions(ctx context.Context, userID, chatI } if !isOwner { - return nil, errors.New("No authorization.") + return nil, errors.New("no authorization") } // items_per_page == 0 returns an empty list (mirrors Python's list_sessions). @@ -299,7 +299,7 @@ func (s *ChatSessionService) GetSession(ctx context.Context, userID, chatID, ses return nil, common.CodeServerError, err } if !ok { - return nil, common.CodeAuthenticationError, errors.New("No authorization.") + return nil, common.CodeAuthenticationError, errors.New("no authorization") } session, err := s.chatSessionDAO.GetByID(ctx, dao.DB, sessionID) @@ -328,7 +328,7 @@ func (s *ChatSessionService) CreateSession(ctx context.Context, userID, chatID s return nil, common.CodeServerError, err } if !ok { - return nil, common.CodeAuthenticationError, errors.New("No authorization.") + return nil, common.CodeAuthenticationError, errors.New("no authorization") } dialog, err := s.chatSessionDAO.GetDialogByID(ctx, dao.DB, chatID) @@ -394,7 +394,7 @@ func (s *ChatSessionService) DeleteSessions(ctx context.Context, userID, chatID return nil, "", common.CodeServerError, err } if !ok { - return false, "No authorization.", common.CodeAuthenticationError, errors.New("No authorization.") + return false, "no authorization", common.CodeAuthenticationError, errors.New("no authorization") } if len(req) == 0 { @@ -552,7 +552,7 @@ func (s *ChatSessionService) UpdateSession(ctx context.Context, userID, chatID, return nil, common.CodeServerError, err } if !ok { - return nil, common.CodeAuthenticationError, errors.New("No authorization.") + return nil, common.CodeAuthenticationError, errors.New("no authorization") } if _, err = s.chatSessionDAO.GetBySessionIDAndChatID(ctx, dao.DB, sessionID, chatID); err != nil { @@ -621,7 +621,7 @@ func (s *ChatSessionService) DeleteSessionMessage(ctx context.Context, userID, c return nil, common.CodeServerError, err } if !ok { - return nil, common.CodeAuthenticationError, errors.New("No authorization.") + return nil, common.CodeAuthenticationError, errors.New("no authorization") } session, err := s.chatSessionDAO.GetByID(ctx, dao.DB, sessionID) @@ -711,7 +711,7 @@ func (s *ChatSessionService) UpdateMessageFeedback(ctx context.Context, userID, } ok := ownerTenantID != "" if !ok { - return nil, common.CodeAuthenticationError, errors.New("No authorization.") + return nil, common.CodeAuthenticationError, errors.New("no authorization") } session, err := s.chatSessionDAO.GetByID(ctx, dao.DB, sessionID) @@ -1490,7 +1490,7 @@ func (s *ChatSessionService) ChatCompletions( var session *entity.ChatSession if chatID != "" { if err = s.checkDialogOwnership(ctx, userID, chatID); err != nil { - return fail(common.NewCodedError(common.CodeAuthenticationError, "No authorization.")) + return fail(common.NewCodedError(common.CodeAuthenticationError, "no authorization")) } dialog, err = s.chatSessionDAO.GetDialogByID(ctx, dao.DB, chatID) if err != nil { @@ -1811,7 +1811,7 @@ func (s *ChatSessionService) checkDialogOwnership(ctx context.Context, userID, c return err } if !ok { - return errors.New("No authorization.") + return errors.New("no authorization") } return nil } diff --git a/internal/service/chat_session_contract_test.go b/internal/service/chat_session_contract_test.go index 5e700c3c7c..1682f8d681 100644 --- a/internal/service/chat_session_contract_test.go +++ b/internal/service/chat_session_contract_test.go @@ -118,7 +118,7 @@ func TestCreateSession_NotOwner(t *testing.T) { ctx := t.Context() _, code, err := svc.CreateSession(ctx, "user-1", "chat-1", map[string]interface{}{"name": "x"}) - if err == nil || err.Error() != "No authorization." { + if err == nil || err.Error() != "no authorization" { t.Fatalf("err=%v", err) } if code != common.CodeAuthenticationError { @@ -208,7 +208,7 @@ func TestDeleteSessions_NotOwner(t *testing.T) { ctx := t.Context() _, _, code, err := svc.DeleteSessions(ctx, "user-1", "chat-1", map[string]interface{}{"ids": []interface{}{"s1"}}) - if err == nil || err.Error() != "No authorization." { + if err == nil || err.Error() != "no authorization" { t.Fatalf("err=%v", err) } if code != common.CodeAuthenticationError { diff --git a/internal/service/chat_session_test.go b/internal/service/chat_session_test.go index 4b11ec711b..a58ece3699 100644 --- a/internal/service/chat_session_test.go +++ b/internal/service/chat_session_test.go @@ -324,7 +324,7 @@ func TestListChatSessions_NotOwner(t *testing.T) { ctx := t.Context() _, err := svc.ListChatSessions(ctx, "user-1", "chat-1", "", "", "create_time", true, 1, 30) - if err == nil || !strings.Contains(err.Error(), "No authorization") { + if err == nil || !strings.Contains(err.Error(), "no authorization") { t.Fatalf("got %v", err) } } @@ -401,7 +401,7 @@ func TestGetSession_NotOwner(t *testing.T) { ctx := t.Context() _, code, err := svc.GetSession(ctx, "user-1", "chat-1", "session-1") - if err == nil || err.Error() != "No authorization." { + if err == nil || err.Error() != "no authorization" { t.Fatalf("err=%v", err) } if code != common.CodeAuthenticationError { diff --git a/internal/service/chunk/chunk.go b/internal/service/chunk/chunk.go index 76bd75a71d..1db2270e65 100644 --- a/internal/service/chunk/chunk.go +++ b/internal/service/chunk/chunk.go @@ -769,7 +769,7 @@ func (s *ChunkService) Parse(ctx context.Context, userID, datasetID string, req return map[string]interface{}{ "success_count": successCount, "errors": duplicateMessages, - }, common.CodeSuccess, fmt.Errorf("Partially parsed %d documents with %d errors", successCount, len(duplicateMessages)) + }, common.CodeSuccess, fmt.Errorf("partially parsed %d documents with %d errors", successCount, len(duplicateMessages)) } return nil, common.CodeDataError, fmt.Errorf("%s", strings.Join(duplicateMessages, ";")) } diff --git a/internal/service/compilation_template_service.go b/internal/service/compilation_template_service.go index bbe04fe04b..81e3805e5e 100644 --- a/internal/service/compilation_template_service.go +++ b/internal/service/compilation_template_service.go @@ -188,34 +188,34 @@ func ValidateTemplatePayload(req map[string]interface{}, requireAll bool) error if requireAll { for _, key := range []string{"name", "kind", "config"} { if _, ok := req[key]; !ok { - return fmt.Errorf("missing required field: %s.", key) + return fmt.Errorf("missing required field: %s", key) } } } if name, ok := req["name"]; ok { nameStr, ok2 := name.(string) if !ok2 || strings.TrimSpace(nameStr) == "" || len([]byte(nameStr)) > 128 { - return errors.New("invalid template name.") + return errors.New("invalid template name") } } if desc, ok := req["description"]; ok { if descStr, ok2 := desc.(string); !ok2 || len(descStr) > 1024 { - return errors.New("invalid template description.") + return errors.New("invalid template description") } } if kind, ok := req["kind"]; ok { if kindStr, ok2 := kind.(string); !ok2 || kindStr == "" { - return errors.New("invalid template kind.") + return errors.New("invalid template kind") } } config, hasConfig := req["config"] if hasConfig { configMap, ok := config.(map[string]interface{}) if !ok { - return errors.New("invalid template config.") + return errors.New("invalid template config") } if len(fmt.Sprint(configMap["global_rules"])) > 4096 { - return errors.New("global compilation rules is too long.") + return errors.New("global compilation rules is too long") } for _, section := range []string{"entity", "relation"} { sec, _ := configMap[section].(map[string]interface{}) @@ -225,20 +225,20 @@ func ValidateTemplatePayload(req map[string]interface{}, requireAll bool) error fm, _ := f.(map[string]interface{}) fieldType := strings.TrimSpace(yamlStr(fm["type"])) if fieldType == "" { - return fmt.Errorf("%s type is required.", capitalizeTitle(section)) + return fmt.Errorf("%s type is required", capitalizeTitle(section)) } if _, dup := seen[fieldType]; dup { - return fmt.Errorf("%s type can not be duplicated.", capitalizeTitle(section)) + return fmt.Errorf("%s type can not be duplicated", capitalizeTitle(section)) } seen[fieldType] = struct{}{} if strings.TrimSpace(yamlStr(fm["description"])) == "" { - return fmt.Errorf("%s field description is required.", capitalizeTitle(section)) + return fmt.Errorf("%s field description is required", capitalizeTitle(section)) } if len(yamlStr(fm["description"])) > 1024 { - return fmt.Errorf("%s field description is too long.", capitalizeTitle(section)) + return fmt.Errorf("%s field description is too long", capitalizeTitle(section)) } if len(yamlStr(fm["rule"])) > 1024 { - return fmt.Errorf("%s field rule is too long.", capitalizeTitle(section)) + return fmt.Errorf("%s field rule is too long", capitalizeTitle(section)) } } } @@ -251,29 +251,29 @@ func ValidateTemplatePayload(req map[string]interface{}, requireAll bool) error switch group { case "claim": if strings.TrimSpace(yamlStr(fm["statement"])) == "" { - return errors.New("claim statement is required.") + return errors.New("claim statement is required") } if strings.TrimSpace(yamlStr(fm["subject"])) == "" { - return errors.New("claim subject is required.") + return errors.New("claim subject is required") } if len(yamlStr(fm["statement"])) > 1024 { - return errors.New("claim statement is too long.") + return errors.New("claim statement is too long") } if len(yamlStr(fm["subject"])) > 1024 { - return errors.New("claim subject is too long.") + return errors.New("claim subject is too long") } case "concept": if strings.TrimSpace(yamlStr(fm["term"])) == "" { - return errors.New("concept term is required.") + return errors.New("concept term is required") } if strings.TrimSpace(yamlStr(fm["definition_excerpt"])) == "" { - return errors.New("concept definition excerpt is required.") + return errors.New("concept definition excerpt is required") } if len(yamlStr(fm["term"])) > 1024 { - return errors.New("concept term is too long.") + return errors.New("concept term is too long") } if len(yamlStr(fm["definition_excerpt"])) > 1024 { - return errors.New("concept definition excerpt is too long.") + return errors.New("concept definition excerpt is too long") } } } diff --git a/internal/service/dataset/crud.go b/internal/service/dataset/crud.go index 959b2356b2..a2889a3203 100644 --- a/internal/service/dataset/crud.go +++ b/internal/service/dataset/crud.go @@ -331,7 +331,7 @@ func (d *DatasetService) deleteDataset(tenantID string, kb *entity.Knowledgebase func (d *DatasetService) ListDatasets(ctx context.Context, id, name string, page, pageSize int, orderby string, desc bool, keywords string, ownerIDs []string, parserID, userID string, ids []string) ([]map[string]interface{}, int64, common.ErrorCode, error) { id = strings.TrimSpace(id) if id != "" && len(ids) > 0 { - return nil, 0, common.CodeDataError, fmt.Errorf("Should not provide both 'id':%s and 'ids'%s", id, pythonStringListRepr(ids)) + return nil, 0, common.CodeDataError, fmt.Errorf("should not provide both 'id':%s and 'ids':%s", id, pythonStringListRepr(ids)) } if id != "" { normalizedID, err := normalizeDatasetID(id) @@ -441,7 +441,7 @@ func (d *DatasetService) ListDatasets(ctx context.Context, id, name string, page } } if len(deniedIDs) > 0 { - return nil, 0, common.CodeDataError, fmt.Errorf("User '%s' lacks permission for datasets: '%s'", userID, strings.Join(deniedIDs, ", ")) + return nil, 0, common.CodeDataError, fmt.Errorf("user '%s' lacks permission for datasets: '%s'", userID, strings.Join(deniedIDs, ", ")) } } diff --git a/internal/service/dataset/list_test.go b/internal/service/dataset/list_test.go index 7c2e072c9c..c43e1b7d90 100644 --- a/internal/service/dataset/list_test.go +++ b/internal/service/dataset/list_test.go @@ -90,7 +90,7 @@ func TestDatasetServiceListDatasetsRejectsIDAndIDsTogether(t *testing.T) { if code != common.CodeDataError { t.Fatalf("expected data error code, got %d", code) } - expected := "Should not provide both 'id':kb-1 and 'ids'['kb-1']" + expected := "should not provide both 'id':kb-1 and 'ids':['kb-1']" if err.Error() != expected { t.Fatalf("unexpected error: %v", err) } @@ -112,7 +112,7 @@ func TestDatasetServiceListDatasetsRejectsDeniedIDs(t *testing.T) { if code != common.CodeDataError { t.Fatalf("expected data error code, got %d", code) } - expected := "User 'user-1' lacks permission for datasets: 'kb-private'" + expected := "user 'user-1' lacks permission for datasets: 'kb-private'" if !strings.Contains(err.Error(), expected) { t.Fatalf("unexpected error: %v", err) } diff --git a/internal/service/dataset_artifact_service.go b/internal/service/dataset_artifact_service.go index af9a210a50..1e91220679 100644 --- a/internal/service/dataset_artifact_service.go +++ b/internal/service/dataset_artifact_service.go @@ -36,14 +36,12 @@ const ( CompileKwdDatasetNav = "dataset_nav" CompileKwdRaptorGraph = "raptor_graph" - // Structure / graph compilation keywords. CompileKwdStructure = "structure" CompileKwdStructureIndex = "structureIndex" CompileKwdStructureEntity = "structureEntity" CompileKwdStructureRelation = "structureRelation" CompileKwdStructureCommunity = "structureCommunity" - // Field name for the structure index type discriminator. FieldStructureIndexType = "structure_index_type" FieldStructureKind = "structure_kind" FieldPageID = "page_id" diff --git a/internal/service/deep_researcher.go b/internal/service/deep_researcher.go index 24db418b0c..38897e670c 100644 --- a/internal/service/deep_researcher.go +++ b/internal/service/deep_researcher.go @@ -232,7 +232,7 @@ func (dr *DeepResearcher) _research( // 1. Retrieve information (KB + optional web) st := time.Now() - kbinfos, err := dr._retrieve_information(ctx, query) + kbinfos, err := dr.retrieveInformation(ctx, query) if err != nil { return "", err } @@ -340,8 +340,8 @@ func (dr *DeepResearcher) _research( // Retrieval (KB + optional Web) // ────────────────────────────────────────────────────────────────────── -// _retrieve_information does KB + optional web retrieval. -func (dr *DeepResearcher) _retrieve_information(ctx context.Context, query string) (map[string]interface{}, error) { +// retrieveInformation does KB + optional web retrieval. +func (dr *DeepResearcher) retrieveInformation(ctx context.Context, query string) (map[string]interface{}, error) { kbinfos := map[string]interface{}{ "total": int64(0), "chunks": []map[string]interface{}{}, diff --git a/internal/service/document/document.go b/internal/service/document/document.go index 4df6d19b97..3348660565 100644 --- a/internal/service/document/document.go +++ b/internal/service/document/document.go @@ -131,7 +131,6 @@ type UpdateDatasetDocumentRequest struct { ParseType *int `json:"parse_type,omitempty"` } -// PATCH /api/v1/datasets/:dataset_id/documents/:document_id. type UpdateDatasetDocumentResponse struct { ID string `json:"id"` Thumbnail *string `json:"thumbnail,omitempty"` @@ -163,9 +162,9 @@ type UpdateDatasetDocumentResponse struct { } var ( - ErrArtifactInvalidFilename = errors.New("Invalid filename.") - ErrArtifactInvalidFileType = errors.New("Invalid file type.") - ErrArtifactNotFound = errors.New("Artifact not found.") + ErrArtifactInvalidFilename = errors.New("invalid filename") + ErrArtifactInvalidFileType = errors.New("invalid file type") + ErrArtifactNotFound = errors.New("artifact not found") ) var artifactContentTypes = map[string]string{ diff --git a/internal/service/document/document_crud.go b/internal/service/document/document_crud.go index 48fa9fb38b..d40a814f5f 100644 --- a/internal/service/document/document_crud.go +++ b/internal/service/document/document_crud.go @@ -67,11 +67,11 @@ func (s *DocumentService) GetDocumentStorageAddress(ctx context.Context, doc *en func (s *DocumentService) DownloadDocument(ctx context.Context, datasetID, docID string) (*DownloadDocumentResp, error) { if docID == "" { - return nil, fmt.Errorf("Specify document_id please.") + return nil, fmt.Errorf("specify document_id please") } doc, err := s.documentDAO.GetByID(ctx, dao.DB, docID) if err != nil || doc.KbID != datasetID { - return nil, fmt.Errorf("Document not found!") + return nil, fmt.Errorf("document not found") } bucket, name, err := s.GetDocumentStorageAddress(ctx, doc) if err != nil { @@ -88,7 +88,7 @@ func (s *DocumentService) DownloadDocument(ctx context.Context, datasetID, docID return nil, err } if len(data) == 0 { - return nil, fmt.Errorf("This file is empty.") + return nil, fmt.Errorf("this document is empty") } fileName := "" diff --git a/internal/service/document/document_dataset_update.go b/internal/service/document/document_dataset_update.go index c22717a728..9d3cc1b0cf 100644 --- a/internal/service/document/document_dataset_update.go +++ b/internal/service/document/document_dataset_update.go @@ -240,17 +240,17 @@ func (s *DocumentService) validateDatasetDocumentUpdate(ctx context.Context, dat return common.CodeDataError, errors.New("invalid request payload") } if present["chunk_count"] && req.ChunkCount != nil && *req.ChunkCount != 0 && *req.ChunkCount != doc.ChunkNum { - return common.CodeDataError, errors.New("Can't change `chunk_count`.") + return common.CodeDataError, errors.New("can't change `chunk_count`") } if present["token_count"] && req.TokenCount != nil && *req.TokenCount != 0 && *req.TokenCount != doc.TokenNum { - return common.CodeDataError, errors.New("Can't change `token_count`.") + return common.CodeDataError, errors.New("can't change `token_count`") } if present["progress"] && req.Progress != nil { if *req.Progress > 1 { return common.CodeDataError, fmt.Errorf("Field: - Message: - Value: <%s>", pythonFloatRepr(*req.Progress)) } if *req.Progress != 0 && math.Abs(*req.Progress-doc.Progress) > 1e-9 { - return common.CodeDataError, errors.New("Can't change `progress`.") + return common.CodeDataError, errors.New("can't change `progress`") } } @@ -319,7 +319,7 @@ func (s *DocumentService) validateDocumentName(ctx context.Context, doc *entity. } if strings.ToLower(filepath.Ext(newName)) != strings.ToLower(filepath.Ext(oldName)) { - return common.CodeArgumentError, errors.New("The extension of file can't be changed") + return common.CodeArgumentError, errors.New("the extension of file can't be changed") } docs, err := s.documentDAO.GetByNameAndKBID(ctx, dao.DB, newName, doc.KbID) @@ -328,7 +328,7 @@ func (s *DocumentService) validateDocumentName(ctx context.Context, doc *entity. } for _, d := range docs { if d.ID != doc.ID && d.Name != nil && *d.Name == newName { - return common.CodeDataError, errors.New("Duplicated document name in the same dataset.") + return common.CodeDataError, errors.New("duplicated document name in the same dataset") } } diff --git a/internal/service/document/document_metadata.go b/internal/service/document/document_metadata.go index a8757f35db..4d112513fb 100644 --- a/internal/service/document/document_metadata.go +++ b/internal/service/document/document_metadata.go @@ -594,7 +594,7 @@ func (s *DocumentService) BatchUpdateDocumentMetadatas( } } if len(invalidIDs) > 0 { - return nil, common.CodeDataError, fmt.Errorf("These documents do not belong to dataset %s: %s", + return nil, common.CodeDataError, fmt.Errorf("these documents do not belong to dataset %s: %s", datasetID, strings.Join(invalidIDs, ", ")) } for _, id := range selector.DocumentIDs { @@ -610,7 +610,7 @@ func (s *DocumentService) BatchUpdateDocumentMetadatas( } // ParseAndConvert mirrors Python convert_conditions: conditions arrive as - // {name, comparison_operator, value}, the operator is normalised, and the + // {name, comparison_operator, value}, the operator is normalized, and the // (possibly non-string) value is preserved. MetaFilter then matches against // the common.MetaData returned by GetFlattedMetaByKBs. filterInput := common.ParseAndConvert(selector.MetadataCondition) @@ -685,17 +685,17 @@ func validateBatchUpdateDocumentMetadatasRequest( ) (common.ErrorCode, error) { for _, upd := range updates { if strings.TrimSpace(upd.Key) == "" || upd.Value == nil { - return common.CodeDataError, errors.New("Each update requires key and value.") + return common.CodeDataError, errors.New("each update requires key and value") } } for _, del := range deletes { if strings.TrimSpace(del.Key) == "" { - return common.CodeDataError, errors.New("Each delete requires key.") + return common.CodeDataError, errors.New("each delete requires key") } } if selector != nil && selector.MetadataCondition != nil { if _, ok := selector.MetadataCondition["conditions"]; !ok && len(selector.MetadataCondition) > 0 { - return common.CodeDataError, errors.New("metadata_condition must be an object.") + return common.CodeDataError, errors.New("metadata_condition must be an object") } } return common.CodeSuccess, nil diff --git a/internal/service/document/document_test.go b/internal/service/document/document_test.go index 29941d0a9f..2a69b61b3d 100644 --- a/internal/service/document/document_test.go +++ b/internal/service/document/document_test.go @@ -861,7 +861,7 @@ func insertUserTenantForAccessCheck(t *testing.T, userID, tenantID string) { var existingUser entity.User if err := dao.DB.Where("id = ?", userID).First(&existingUser).Error; err != nil { u := &entity.User{ID: userID, Nickname: "test-user", Email: userID + "@test.com", Password: sptr("x")} - if err := dao.DB.Create(u).Error; err != nil { + if err = dao.DB.Create(u).Error; err != nil { t.Fatalf("insert test user: %v", err) } } @@ -874,7 +874,7 @@ func insertUserTenantForAccessCheck(t *testing.T, userID, tenantID string) { EmbdID: "embd-default", ASRID: "asr-default", } - if err := dao.DB.Create(tn).Error; err != nil { + if err = dao.DB.Create(tn).Error; err != nil { t.Fatalf("insert test tenant: %v", err) } } @@ -887,7 +887,7 @@ func insertUserTenantForAccessCheck(t *testing.T, userID, tenantID string) { TenantID: tenantID, Role: "admin", } - if err := dao.DB.Create(ut).Error; err != nil { + if err = dao.DB.Create(ut).Error; err != nil { t.Fatalf("insert test user_tenant: %v", err) } } @@ -1644,7 +1644,7 @@ func TestUpdateDatasetDocumentRejectsCounterMutation(t *testing.T) { if code != common.CodeDataError { t.Fatalf("code = %v, want %v", code, common.CodeDataError) } - if err.Error() != "Can't change `chunk_count`." { + if err.Error() != "can't change `chunk_count`" { t.Fatalf("err = %q", err.Error()) } } @@ -2288,7 +2288,7 @@ func TestBatchUpdateDocumentMetadatasRejectsMissingValue(t *testing.T) { if code != common.CodeDataError { t.Fatalf("code = %v, want data error", code) } - if !strings.Contains(err.Error(), "Each update requires key and value.") { + if !strings.Contains(err.Error(), "each update requires key and value") { t.Fatalf("err = %v", err) } } diff --git a/internal/service/file/file_content.go b/internal/service/file/file_content.go index 09a8f548a3..55c86d4d5b 100644 --- a/internal/service/file/file_content.go +++ b/internal/service/file/file_content.go @@ -18,7 +18,7 @@ import ( func (s *FileService) GetFileContent(ctx context.Context, uid, fileID string) (*entity.File, error) { file, err := s.fileDAO.GetByID(ctx, dao.DB, fileID) if err != nil || file == nil { - return nil, fmt.Errorf("Document not found!") + return nil, fmt.Errorf("document not found") } if !s.checkFilePerm(ctx, s.fileDAO, file, uid) { return nil, fmt.Errorf("no authorization") diff --git a/internal/service/file/file_upload.go b/internal/service/file/file_upload.go index beca433599..40ad428038 100644 --- a/internal/service/file/file_upload.go +++ b/internal/service/file/file_upload.go @@ -27,7 +27,7 @@ func (s *FileService) UploadFile(ctx context.Context, tenantID, parentID string, _, err := s.fileDAO.GetByID(ctx, dao.DB, parentID) if err != nil { - return nil, fmt.Errorf("Can't find this folder!") + return nil, fmt.Errorf("can't find this folder") } maxFileNumPerUser := common.GetEnv(common.EnvMaxFileNumPerUser) @@ -40,7 +40,7 @@ func (s *FileService) UploadFile(ctx context.Context, tenantID, parentID string, return nil, fmt.Errorf("failed to get document count: %w", err) } if docCount >= maxNum { - return nil, fmt.Errorf("Exceed the maximum file number of a free user!") + return nil, fmt.Errorf("exceed the maximum file number of a free user") } } } @@ -235,12 +235,12 @@ func (s *FileService) checkUploadInfoHealth(ctx context.Context, userID, filenam return fmt.Errorf("failed to get document count: %w", err) } if docCount >= maxNum { - return fmt.Errorf("Exceed the maximum file number of a free user!") + return fmt.Errorf("exceed the maximum file number of a free user") } } } if len([]byte(filename)) > 255 { - return fmt.Errorf("Exceed the maximum length of file name!") + return fmt.Errorf("exceed the maximum length of file name") } return nil } diff --git a/internal/service/model_chat.go b/internal/service/model_chat.go index eba4bd549b..3258f1a196 100644 --- a/internal/service/model_chat.go +++ b/internal/service/model_chat.go @@ -69,7 +69,7 @@ func chatStreamWithContext(ctx context.Context, chatModel *modelModule.ChatModel return ctx.Err() } }); err != nil { - if errors.Is(err, errStreamDone) || err == context.Canceled || err == context.DeadlineExceeded { + if errors.Is(err, errStreamDone) || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return } common.Warn("ChatStreamlyWithSender returned error", zap.Error(err)) diff --git a/internal/service/nlp/retrieval.go b/internal/service/nlp/retrieval.go index 68e0cc61ce..29b16861b0 100644 --- a/internal/service/nlp/retrieval.go +++ b/internal/service/nlp/retrieval.go @@ -148,7 +148,7 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) } searchResult, err := s.Search(ctx, searchReq) if err != nil { - return nil, fmt.Errorf("Search failed: %w", err) + return nil, fmt.Errorf("search failed: %w", err) } // Prune deleted chunks @@ -173,12 +173,12 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) // For Infinity path: use _score directly (scores already normalized during fusion) // For OceanBase path: extract vectors and compute locally var sim []float64 - var term_similarity []float64 - var vector_similarity []float64 + var termSimilarity []float64 + var vectorSimilarity []float64 if req.RerankModel != nil && searchResult.Total > 0 { // External rerank model path - use RerankByModel - sim, term_similarity, vector_similarity = RerankByModel( + sim, termSimilarity, vectorSimilarity = RerankByModel( ctx, req.RerankModel, searchResult.Chunks, @@ -209,16 +209,16 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) sim[i] = 0.0 } } - term_similarity = sim - vector_similarity = sim + termSimilarity = sim + vectorSimilarity = sim } else if useOceanBase { // OceanBase: extract vectors and compute locally (not implemented) sim = make([]float64, len(searchResult.IDs)) for i := range searchResult.IDs { sim[i] = 0.0 } - term_similarity = sim - vector_similarity = sim + termSimilarity = sim + vectorSimilarity = sim } else { // ES PATH: Two-pass KNN approach for clean cosine similarity scores // @@ -248,7 +248,7 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) if err != nil { common.Warn("KNNScores failed for ES, falling back to local computation", zap.Error(err)) // Fallback: RerankStandard computes vector similarity locally (requires shipping vectors) - sim, term_similarity, vector_similarity = RerankStandard( + sim, termSimilarity, vectorSimilarity = RerankStandard( searchResult.Chunks, nil, // keywords computed internally searchResult.QueryVector, @@ -266,7 +266,7 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) // RERANK: Combine token + vector + rank feature similarities // Matches Python's rerank_with_knn(): sim = tkweight * tksim + vtweight * vtsim + rank_fea - sim, term_similarity, vector_similarity = RerankWithKNN( + sim, termSimilarity, vectorSimilarity = RerankWithKNN( searchResult.Chunks, searchResult.IDs, searchResult.Field, @@ -414,8 +414,8 @@ func (s *RetrievalService) Retrieval(ctx context.Context, req *RetrievalRequest) resultChunk["row_id"] = v } resultChunk["similarity"] = sim[i] - resultChunk["term_similarity"] = term_similarity[i] - resultChunk["vector_similarity"] = vector_similarity[i] + resultChunk["term_similarity"] = termSimilarity[i] + resultChunk["vector_similarity"] = vectorSimilarity[i] // Always set these fields even if empty, to match Python response format if v, ok := chunk["important_kwd"]; ok { @@ -621,7 +621,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque searchRequest.MatchExprs = []interface{}{} engineResult, err = s.docEngine.Search(ctx, searchRequest) if err != nil { - return nil, fmt.Errorf("Search failed: %w", err) + return nil, fmt.Errorf("search failed: %w", err) } } else { // Non-empty question @@ -641,7 +641,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque engineResult, err = s.docEngine.Search(ctx, &searchRequestWithRank) if err != nil { - return nil, fmt.Errorf("Search failed: %w", err) + return nil, fmt.Errorf("search failed: %w", err) } queryVector = nil } else { @@ -675,7 +675,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque engineResult, err = s.docEngine.Search(ctx, searchRequest) if err != nil { - return nil, fmt.Errorf("Search failed: %w", err) + return nil, fmt.Errorf("search failed: %w", err) } // If result is empty, retry with relaxed conditions if engineResult.Total == 0 { @@ -699,7 +699,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque engineResult, err = s.docEngine.Search(ctx, searchRequest) if err != nil { - return nil, fmt.Errorf("Search retry failed: %w", err) + return nil, fmt.Errorf("search retry failed: %w", err) } } else { // No doc_id filter — retry with lower min_match (0.1 vs default 0.3) @@ -713,7 +713,7 @@ func (s *RetrievalService) Search(ctx context.Context, req *RetrievalSearchReque engineResult, err = s.docEngine.Search(ctx, searchRequest) if err != nil { - return nil, fmt.Errorf("Search retry failed: %w", err) + return nil, fmt.Errorf("search retry failed: %w", err) } } } diff --git a/internal/service/pipeline_params.go b/internal/service/pipeline_params.go index 9e05ba2095..88fbf0d23a 100644 --- a/internal/service/pipeline_params.go +++ b/internal/service/pipeline_params.go @@ -120,10 +120,10 @@ func ValidateDatasetEmbeddingModels(kbs []*entity.Knowledgebase) error { } } if hasEmbd && noEmbd { - return fmt.Errorf("Cannot search across datasets where some have embedding models and others do not.") + return fmt.Errorf("cannot search across datasets where some have embedding models and others do not") } if len(embdIDs) > 1 { - return fmt.Errorf("Datasets use different embedding models: %v", getEmbdIDs(kbs)) + return fmt.Errorf("datasets use different embedding models: %v", getEmbdIDs(kbs)) } return nil } diff --git a/internal/service/pipeline_params_test.go b/internal/service/pipeline_params_test.go index 38ea632132..a9da3ccbce 100644 --- a/internal/service/pipeline_params_test.go +++ b/internal/service/pipeline_params_test.go @@ -35,7 +35,7 @@ func TestValidateDatasetEmbeddingModels_MixedErrors(t *testing.T) { if err == nil { t.Fatal("expected error for mixed embedding") } - if err.Error() != "Cannot search across datasets where some have embedding models and others do not." { + if err.Error() != "cannot search across datasets where some have embedding models and others do not" { t.Errorf("unexpected error: %v", err) } } diff --git a/test/testcases/restful_api/test_document_raw_routes.py b/test/testcases/restful_api/test_document_raw_routes.py index 97bd3d3fd2..254cb98d10 100644 --- a/test/testcases/restful_api/test_document_raw_routes.py +++ b/test/testcases/restful_api/test_document_raw_routes.py @@ -45,7 +45,7 @@ def test_document_download_by_id_invalid_id_contract(rest_client): assert res.status_code == 200 payload = res.json() assert payload["code"] == 102, payload - assert payload["message"] == "Document not found!", payload + assert payload["message"] == "document not found", payload @pytest.mark.p2 @@ -62,4 +62,4 @@ def test_document_artifact_rejects_unsafe_filename(rest_client): assert res.status_code == 200 payload = res.json() assert payload["code"] == 102, payload - assert payload["message"] == "Invalid file type.", payload + assert payload["message"] == "invalid file type", payload diff --git a/test/testcases/restful_api/test_documents.py b/test/testcases/restful_api/test_documents.py index 238322778f..c10e12f417 100644 --- a/test/testcases/restful_api/test_documents.py +++ b/test/testcases/restful_api/test_documents.py @@ -690,12 +690,12 @@ def test_documents_update_invalid_field_and_guard_contract(rest_client, create_d first_document_id = uploaded_docs[0]["id"] strict_guard_cases = [ - ({"chunk_count": 1}, 102, "Can't change `chunk_count`."), - ({"token_count": 1}, 102, "Can't change `token_count`."), - ({"chunk_count": 100}, 102, "Can't change `chunk_count`."), - ({"token_count": 100}, 102, "Can't change `token_count`."), + ({"chunk_count": 1}, 102, "can't change `chunk_count`"), + ({"token_count": 1}, 102, "can't change `token_count`"), + ({"chunk_count": 100}, 102, "can't change `chunk_count`"), + ({"token_count": 100}, 102, "can't change `token_count`"), ({"progress": 2.0}, 102, "Field: - Message: - Value: <2.0>"), - ({"progress": 1.0}, 102, "Can't change `progress`."), + ({"progress": 1.0}, 102, "can't change `progress`"), ({"meta_fields": []}, 102, "Field: - Message: - Value: <[]>"), ] for payload, expected_code, expected_message in strict_guard_cases: @@ -1491,14 +1491,14 @@ def test_documents_download_requires_auth_and_invalid_id_contract(rest_client, c assert invalid_doc_res.status_code == 200 invalid_doc_payload = invalid_doc_res.json() assert invalid_doc_payload["code"] == 102, invalid_doc_payload - assert invalid_doc_payload["message"] == "Document not found!", invalid_doc_payload + assert invalid_doc_payload["message"] == "document not found", invalid_doc_payload invalid_dataset_path = tmp_path / "invalid_dataset_download.txt" invalid_dataset_res = _download_document_to_file(rest_client, "invalid_dataset_id", document_id, invalid_dataset_path) assert invalid_dataset_res.status_code == 200 invalid_dataset_payload = invalid_dataset_res.json() assert invalid_dataset_payload["code"] == 102, invalid_dataset_payload - assert invalid_dataset_payload["message"] == "Document not found!", invalid_dataset_payload + assert invalid_dataset_payload["message"] == "document not found", invalid_dataset_payload @pytest.mark.p2 diff --git a/test/testcases/test_http_api/test_file_management_within_dataset/test_update_document.py b/test/testcases/test_http_api/test_file_management_within_dataset/test_update_document.py index f1fe170b93..7b8925399d 100644 --- a/test/testcases/test_http_api/test_file_management_within_dataset/test_update_document.py +++ b/test/testcases/test_http_api/test_file_management_within_dataset/test_update_document.py @@ -221,7 +221,7 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_code, expected_message", [ - ({"chunk_count": 1}, 102, "Can't change `chunk_count`."), + ({"chunk_count": 1}, 102, "can't change `chunk_count`"), pytest.param( {"create_date": "Fri, 14 Mar 2025 16:53:42 GMT"}, 102, @@ -270,7 +270,7 @@ class TestDocumentsUpdated: "The input parameters are invalid.", marks=pytest.mark.skip(reason="issues/6104"), ), - pytest.param({"progress": 1.0}, 102, "Can't change `progress`."), + pytest.param({"progress": 1.0}, 102, "can't change `progress`"), pytest.param( {"progress_msg": "ragflow_test"}, 102, @@ -301,7 +301,7 @@ class TestDocumentsUpdated: "The input parameters are invalid.", marks=pytest.mark.skip(reason="issues/6104"), ), - ({"token_count": 1}, 102, "Can't change `token_count`."), + ({"token_count": 1}, 102, "can't change `token_count`"), pytest.param( {"type": "ragflow_test"}, 102, @@ -339,10 +339,10 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_code, expected_message", [ - ({"chunk_count": 100}, 102, "Can't change `chunk_count`."), - ({"token_count": 100}, 102, "Can't change `token_count`."), + ({"chunk_count": 100}, 102, "can't change `chunk_count`"), + ({"token_count": 100}, 102, "can't change `token_count`"), ({"progress": 2.0}, 102, "Field: - Message: - Value: <2.0>"), - ({"progress": 1.0}, 102, "Can't change `progress`."), + ({"progress": 1.0}, 102, "can't change `progress`"), ({"meta_fields": []}, 102, "Field: - Message: - Value: <[]>"), ], ) diff --git a/test/testcases/test_sdk_api/test_file_management_within_dataset/test_update_document.py b/test/testcases/test_sdk_api/test_file_management_within_dataset/test_update_document.py index e79244d4d0..9ad523b498 100644 --- a/test/testcases/test_sdk_api/test_file_management_within_dataset/test_update_document.py +++ b/test/testcases/test_sdk_api/test_file_management_within_dataset/test_update_document.py @@ -148,7 +148,7 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_message", [ - ({"chunk_count": 1}, "Can't change `chunk_count`"), + ({"chunk_count": 1}, "can't change `chunk_count`"), pytest.param( {"create_date": "Fri, 14 Mar 2025 16:53:42 GMT"}, "The input parameters are invalid", @@ -189,7 +189,7 @@ class TestDocumentsUpdated: "The input parameters are invalid", marks=pytest.mark.skip(reason="issues/6104"), ), - ({"progress": 1.0}, "Can't change `progress`"), + ({"progress": 1.0}, "can't change `progress`"), pytest.param( {"progress_msg": "ragflow_test"}, "The input parameters are invalid", @@ -215,7 +215,7 @@ class TestDocumentsUpdated: "The input parameters are invalid", marks=pytest.mark.skip(reason="issues/6104"), ), - ({"token_count": 1}, "Can't change `token_count`"), + ({"token_count": 1}, "can't change `token_count`"), pytest.param( {"type": "ragflow_test"}, "The input parameters are invalid", @@ -245,7 +245,7 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_message", [ - ({"chunk_count": 1}, "Can't change `chunk_count`"), + ({"chunk_count": 1}, "can't change `chunk_count`"), ], ) def test_immutable_fields_chunk_count(self, add_documents, payload, expected_message): @@ -260,7 +260,7 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_message", [ - ({"token_count": 9999}, "Can't change `token_count`"), # Attempt to change immutable field + ({"token_count": 9999}, "can't change `token_count`"), # Attempt to change immutable field ], ) def test_immutable_fields_token_count(self, add_documents, payload, expected_message): @@ -275,7 +275,7 @@ class TestDocumentsUpdated: @pytest.mark.parametrize( "payload, expected_message", [ - ({"progress": 0.5}, "Can't change `progress`"), # Attempt to change immutable field + ({"progress": 0.5}, "can't change `progress`"), # Attempt to change immutable field ({"progress": 1.5}, "Field: - Message: - Value: <1.5>"), # Attempt to change immutable field ], ) diff --git a/test/testcases/test_web_api/test_document_app/test_document_metadata.py b/test/testcases/test_web_api/test_document_app/test_document_metadata.py index badc951ca3..eb49e9294e 100644 --- a/test/testcases/test_web_api/test_document_app/test_document_metadata.py +++ b/test/testcases/test_web_api/test_document_app/test_document_metadata.py @@ -335,7 +335,7 @@ class TestDocumentMetadataUnit: def test_get_route_not_found_success_and_exception_unit(self, document_app_module, monkeypatch): module = document_app_module - # Cross-tenant access is denied -> "Document not found!" (no ID enumeration). + # Cross-tenant access is denied -> "document not found" (no ID enumeration). # Stub get_by_id to a valid document so the test can only pass via the # accessible() early return; if that check ever regresses, the route would # proceed and the assertions below would no longer match. @@ -353,7 +353,7 @@ class TestDocumentMetadataUnit: ) res = _run(module.get("doc1")) assert res["code"] == RetCode.DATA_ERROR - assert "Document not found!" in res["message"] + assert "document not found" in res["message"] assert accessible_calls == [("doc1", "user-1")] # From here on the user is authorized; exercise the original branches. @@ -362,7 +362,7 @@ class TestDocumentMetadataUnit: monkeypatch.setattr(module.DocumentService, "get_by_id", lambda _doc_id: (False, None)) res = _run(module.get("doc1")) assert res["code"] == RetCode.DATA_ERROR - assert "Document not found!" in res["message"] + assert "document not found" in res["message"] async def fake_thread_pool_exec(*_args, **_kwargs): return b"blob-data" @@ -396,7 +396,7 @@ class TestDocumentMetadataUnit: module = document_app_module monkeypatch.setattr(module, "request", _DummyRequest(args={"ext": "abc"})) - # Cross-tenant access is denied -> "Document not found!" (no ID enumeration). + # Cross-tenant access is denied -> "document not found" (no ID enumeration). accessible_calls = [] def fake_accessible_denied(doc_id, user_id): @@ -406,7 +406,7 @@ class TestDocumentMetadataUnit: monkeypatch.setattr(module.DocumentService, "accessible", fake_accessible_denied) res = _run(module.download_attachment(attachment_id="att1")) assert res["code"] == RetCode.DATA_ERROR - assert "Document not found!" in res["message"] + assert "document not found" in res["message"] assert accessible_calls == [("att1", "user-1")] # From here on the user is authorized; exercise the original branches. @@ -447,7 +447,7 @@ class TestDocumentMetadataUnit: res = _run(module.download_document("doc1")) assert res["code"] == RetCode.DATA_ERROR - assert "Document not found!" in res["message"] + assert "document not found" in res["message"] def test_dataset_document_download_rejects_other_tenant_unit(self, document_rest_api_module, monkeypatch): module = document_rest_api_module @@ -456,7 +456,7 @@ class TestDocumentMetadataUnit: res = _run(module.download("kb1", "doc1")) assert res["code"] == RetCode.DATA_ERROR - assert "Document not found!" in res["message"] + assert "document not found" in res["message"] @pytest.mark.p2 def test_get_document_image_content_type_from_object_extension_unit(self, document_app_module, monkeypatch): diff --git a/test/unit_test/api/apps/restful_apis/test_attachment_download_missing_blob.py b/test/unit_test/api/apps/restful_apis/test_attachment_download_missing_blob.py index f37eae9b98..94ecb62f29 100644 --- a/test/unit_test/api/apps/restful_apis/test_attachment_download_missing_blob.py +++ b/test/unit_test/api/apps/restful_apis/test_attachment_download_missing_blob.py @@ -204,7 +204,7 @@ class TestAttachmentDownloadMissingBlob: """Regression for #15502: missing-blob → structured 4xx, not HTTP 500.""" def test_empty_blob_returns_not_found(self, monkeypatch: pytest.MonkeyPatch) -> None: - """Storage returns None (orphaned metadata) → 'Document not found!' 4xx, + """Storage returns None (orphaned metadata) → 'document not found' 4xx, not a TypeError 500 from make_response(None).""" module = _load_agent_api(monkeypatch, storage_get=lambda *_a, **_k: None) result = asyncio.run(module.download_attachment(tenant_id="t1", attachment_id="orphan")) diff --git a/test/unit_test/api/utils/test_doc_validation.py b/test/unit_test/api/utils/test_doc_validation.py index d2f5a0a1fb..e30f1cc02a 100644 --- a/test/unit_test/api/utils/test_doc_validation.py +++ b/test/unit_test/api/utils/test_doc_validation.py @@ -107,7 +107,7 @@ def test_validate_immutable_fields_chunk_count_mismatch(): doc.progress = 0.5 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `chunk_count`." + assert error_msg == "can't change `chunk_count`" assert error_code == RetCode.DATA_ERROR @@ -120,7 +120,7 @@ def test_validate_immutable_fields_token_count_mismatch(): doc.progress = 0.5 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `token_count`." + assert error_msg == "can't change `token_count`" assert error_code == RetCode.DATA_ERROR @@ -133,7 +133,7 @@ def test_validate_immutable_fields_progress_mismatch(): doc.progress = 0.5 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `progress`." + assert error_msg == "can't change `progress`" assert error_code == RetCode.DATA_ERROR @@ -185,7 +185,7 @@ def test_validate_immutable_fields_zero_values_must_match(): doc.progress = 0.5 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `chunk_count`." + assert error_msg == "can't change `chunk_count`" assert error_code == RetCode.DATA_ERROR @@ -198,7 +198,7 @@ def test_validate_immutable_fields_zero_token_count_mismatch_when_chunk_count_ma doc.progress = 0.0 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `token_count`." + assert error_msg == "can't change `token_count`" assert error_code == RetCode.DATA_ERROR @@ -211,7 +211,7 @@ def test_validate_immutable_fields_zero_progress_mismatch_when_counts_match(): doc.progress = 0.5 error_msg, error_code = validate_immutable_fields(update_doc_req, doc) - assert error_msg == "Can't change `progress`." + assert error_msg == "can't change `progress`" assert error_code == RetCode.DATA_ERROR