diff --git a/go.mod b/go.mod index 7aa72113e..8959f065a 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,6 @@ module ragflow go 1.25 require ( - cloud.google.com/go/storage v1.35.1 - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4 - github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.4.4 github.com/aws/aws-sdk-go-v2 v1.41.3 github.com/aws/aws-sdk-go-v2/config v1.32.11 github.com/aws/aws-sdk-go-v2/credentials v1.19.11 @@ -15,8 +10,8 @@ require ( github.com/aws/smithy-go v1.24.2 github.com/elastic/go-elasticsearch/v8 v8.19.1 github.com/gin-gonic/gin v1.9.1 - github.com/go-sql-driver/mysql v1.7.0 github.com/google/uuid v1.6.0 + github.com/infiniflow/infinity-go-sdk v0.0.0-00010101000000-000000000000 github.com/iromli/go-itsdangerous v0.0.0-20220223194502-9c8bef8dac6a github.com/minio/minio-go/v7 v7.0.99 github.com/peterh/liner v1.2.2 @@ -25,18 +20,12 @@ require ( github.com/spf13/viper v1.18.2 go.uber.org/zap v1.27.1 golang.org/x/crypto v0.47.0 - google.golang.org/api v0.153.0 gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.5 ) require ( - cloud.google.com/go v0.110.10 // indirect - cloud.google.com/go/compute v1.23.3 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.5 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect + github.com/apache/thrift v0.22.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.6 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.19 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.19 // indirect @@ -66,13 +55,8 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.16.0 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt/v5 v5.3.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/s2a-go v0.1.7 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -80,7 +64,6 @@ require ( github.com/klauspost/compress v1.18.2 // indirect github.com/klauspost/cpuid/v2 v2.2.11 // indirect github.com/klauspost/crc32 v1.3.0 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -92,7 +75,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/philhofer/fwd v1.2.0 // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -100,11 +83,11 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tinylib/msgp v1.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect @@ -114,18 +97,12 @@ require ( golang.org/x/arch v0.6.0 // indirect golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect golang.org/x/net v0.49.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/text v0.33.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/infiniflow/infinity-go-sdk => github.com/infiniflow/infinity/go v0.0.0-20260317024756-4aff48d0d843 diff --git a/go.sum b/go.sum index 965ceba2d..dd3937594 100644 --- a/go.sum +++ b/go.sum @@ -1,33 +1,5 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= -cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= -cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1 h1:/Zt+cDPnpC3OVDm/JKLOs7M2DKmLRIIp3XIx9pHHiig= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1/go.mod h1:Ng3urmn6dYe8gnbCMoHHVl5APYz2txho3koEkV2o2HA= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4 h1:jWQK1GI+LeGGUKBADtcH2rRqPxYB1Ljwms5gFA2LqrM= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4/go.mod h1:8mwH4klAm9DUgR2EEHyEEAQlRDvLPyg5fQry3y+cDew= -github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.4.4 h1:7QtoGxKm6mPhsWzEZtrn3tQF1hmMMZblngnqNoE61I8= -github.com/Azure/azure-sdk-for-go/sdk/storage/azdatalake v1.4.4/go.mod h1:juYrzH1q6A+g9ZZbGh0OmjS7zaMq3rFDrPhVnYSgFMA= -github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= -github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc= +github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g= github.com/aws/aws-sdk-go-v2 v1.41.3 h1:4kQ/fa22KjDt13QCy1+bYADvdgcxpfH18f0zP542kZA= github.com/aws/aws-sdk-go-v2 v1.41.3/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.6 h1:N4lRUXZpZ1KVEUn6hxtco/1d2lgYhNn1fHkkl8WhlyQ= @@ -73,14 +45,11 @@ github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0 github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -93,10 +62,6 @@ github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/elastic/go-elasticsearch/v8 v8.19.1 h1:0iEGt5/Ds9MNVxEp3hqLsXdbe6SjleaVHONg/FuR09Q= github.com/elastic/go-elasticsearch/v8 v8.19.1/go.mod h1:tHJQdInFa6abmDbDCEH2LJja07l/SIpaGpJcm13nt7s= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -126,49 +91,15 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= -github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/infiniflow/infinity/go v0.0.0-20260317024756-4aff48d0d843 h1:s5g1APIXv4c6hwVL4+DwT5JDvRpegZpxxh2ltZzgeGE= +github.com/infiniflow/infinity/go v0.0.0-20260317024756-4aff48d0d843/go.mod h1:hw3z5AwNFsGy1cdrE0Mfjot2y9jqVHTxBufUx9VzZ+0= github.com/iromli/go-itsdangerous v0.0.0-20220223194502-9c8bef8dac6a h1:Inib12UR9HAfBubrGNraPjKt/Cu8xPbTJbC50+0wP5U= github.com/iromli/go-itsdangerous v0.0.0-20220223194502-9c8bef8dac6a/go.mod h1:8N0Hlye5Lzw+H/yHWpZMkT0QLA+iOHG7KLdvAm95DZg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -177,8 +108,6 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= -github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -187,12 +116,13 @@ github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4O github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -220,12 +150,9 @@ github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs= github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= @@ -270,8 +197,6 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= @@ -293,90 +218,18 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -392,6 +245,4 @@ gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/internal/cli/client.go b/internal/cli/client.go index f69665bb1..af5457d09 100644 --- a/internal/cli/client.go +++ b/internal/cli/client.go @@ -31,9 +31,9 @@ type PasswordPromptFunc func(prompt string) (string, error) // RAGFlowClient handles API interactions with the RAGFlow server type RAGFlowClient struct { - HTTPClient *HTTPClient - ServerType string // "admin" or "user" - PasswordPrompt PasswordPromptFunc // Function for password input + HTTPClient *HTTPClient + ServerType string // "admin" or "user" + PasswordPrompt PasswordPromptFunc // Function for password input } // NewRAGFlowClient creates a new RAGFlow client @@ -489,6 +489,28 @@ func (c *RAGFlowClient) getDatasetID(datasetName string) (string, error) { return "", fmt.Errorf("dataset '%s' not found", datasetName) } +// formatEmptyArray converts empty arrays to "[]" string +func formatEmptyArray(v interface{}) string { + if v == nil { + return "[]" + } + switch val := v.(type) { + case []interface{}: + if len(val) == 0 { + return "[]" + } + case []string: + if len(val) == 0 { + return "[]" + } + case []int: + if len(val) == 0 { + return "[]" + } + } + return fmt.Sprintf("%v", v) +} + // SearchOnDatasets searches for chunks in specified datasets // Returns (result_map, error) - result_map is non-nil for benchmark mode func (c *RAGFlowClient) SearchOnDatasets(cmd *Command) (map[string]interface{}, error) { @@ -582,6 +604,22 @@ func (c *RAGFlowClient) SearchOnDatasets(cmd *Command) (map[string]interface{}, "term_similarity": chunkMap["term_similarity"], "vector_similarity": chunkMap["vector_similarity"], } + // Add optional fields that may be empty arrays + if v, ok := chunkMap["doc_type_kwd"]; ok { + row["doc_type_kwd"] = formatEmptyArray(v) + } + if v, ok := chunkMap["important_kwd"]; ok { + row["important_kwd"] = formatEmptyArray(v) + } + if v, ok := chunkMap["mom_id"]; ok { + row["mom_id"] = formatEmptyArray(v) + } + if v, ok := chunkMap["positions"]; ok { + row["positions"] = formatEmptyArray(v) + } + if v, ok := chunkMap["content_ltks"]; ok { + row["content_ltks"] = v + } tableData = append(tableData, row) } } diff --git a/internal/engine/infinity/client.go b/internal/engine/infinity/client.go index 7c1dbcaac..99e6aadfb 100644 --- a/internal/engine/infinity/client.go +++ b/internal/engine/infinity/client.go @@ -20,24 +20,66 @@ import ( "context" "fmt" "ragflow/internal/server" + "strconv" + "strings" + + infinity "github.com/infiniflow/infinity-go-sdk" ) -// Engine Infinity engine implementation -// Note: Infinity Go SDK is not yet available. This is a placeholder implementation. +// infinityClient Infinity SDK client wrapper +type infinityClient struct { + conn *infinity.InfinityConnection + dbName string +} + +// NewInfinityClient creates a new Infinity client using the SDK +func NewInfinityClient(cfg *server.InfinityConfig) (*infinityClient, error) { + // Parse URI like "localhost:23817" to get IP and port + host := "127.0.0.1" + port := 23817 + + if cfg.URI != "" { + parts := strings.Split(cfg.URI, ":") + if len(parts) == 2 { + host = parts[0] + if p, err := strconv.Atoi(parts[1]); err == nil { + port = p + } + } + } + + conn, err := infinity.Connect(infinity.NetworkAddress{IP: host, Port: port}) + if err != nil { + return nil, fmt.Errorf("failed to connect to Infinity: %w", err) + } + + return &infinityClient{ + conn: conn, + dbName: cfg.DBName, + }, nil +} + +// Engine Infinity engine implementation using Go SDK type infinityEngine struct { config *server.InfinityConfig + client *infinityClient } // NewEngine creates an Infinity engine -// Note: This is a placeholder implementation waiting for official Infinity Go SDK func NewEngine(cfg interface{}) (*infinityEngine, error) { infConfig, ok := cfg.(*server.InfinityConfig) if !ok { return nil, fmt.Errorf("invalid infinity config type, expected *config.InfinityConfig") } + client, err := NewInfinityClient(infConfig) + if err != nil { + return nil, err + } + engine := &infinityEngine{ config: infConfig, + client: client, } return engine, nil @@ -48,12 +90,22 @@ func (e *infinityEngine) Type() string { return "infinity" } -// Ping health check +// Ping checks if Infinity is accessible func (e *infinityEngine) Ping(ctx context.Context) error { - return fmt.Errorf("infinity engine not implemented: waiting for official Go SDK") -} - -// Close closes the connection -func (e *infinityEngine) Close() error { + if e.client == nil || e.client.conn == nil { + return fmt.Errorf("Infinity client not initialized") + } + if !e.client.conn.IsConnected() { + return fmt.Errorf("Infinity not connected") + } + return nil +} + +// Close closes the Infinity connection +func (e *infinityEngine) Close() error { + if e.client != nil && e.client.conn != nil { + _, err := e.client.conn.Disconnect() + return err + } return nil } diff --git a/internal/engine/infinity/search.go b/internal/engine/infinity/search.go index e1aa033c0..53223cf37 100644 --- a/internal/engine/infinity/search.go +++ b/internal/engine/infinity/search.go @@ -19,12 +19,138 @@ package infinity import ( "context" "fmt" + "ragflow/internal/engine/types" "strconv" "strings" + "unicode/utf8" - "ragflow/internal/engine/types" + infinity "github.com/infiniflow/infinity-go-sdk" ) +const ( + PAGERANK_FLD = "pagerank_fea" + TAG_FLD = "tag_feas" +) + +type SortType int + +const ( + SortAsc SortType = 0 + SortDesc SortType = 1 +) + +type OrderByExpr struct { + Fields []OrderByField +} + +type OrderByField struct { + Field string + Type SortType +} + +// fieldKeyword checks if field is a keyword field +func fieldKeyword(fieldName string) bool { + // Treat "*_kwd" tag-like columns as keyword lists except knowledge_graph_kwd + if fieldName == "source_id" { + return true + } + if strings.HasSuffix(fieldName, "_kwd") && + fieldName != "knowledge_graph_kwd" && + fieldName != "docnm_kwd" && + fieldName != "important_kwd" && + fieldName != "question_kwd" { + return true + } + return false +} + +// equivalentConditionToStr converts condition dict to filter string +func equivalentConditionToStr(condition map[string]interface{}, tableColumns map[string]struct { + Type string + Default interface{} +}) string { + if len(condition) == 0 { + return "" + } + + var conditions []string + + for k, v := range condition { + if !strings.HasPrefix(k, "_") { + continue + } + if v == nil || v == "" { + continue + } + + // Handle keyword fields with filter_fulltext + if fieldKeyword(k) { + if listVal, isList := v.([]interface{}); isList { + var orConds []string + for _, item := range listVal { + if strItem, ok := item.(string); ok { + strItem = strings.ReplaceAll(strItem, "'", "''") + orConds = append(orConds, fmt.Sprintf("filter_fulltext('%s', '%s')", convertMatchingField(k), strItem)) + } + } + if len(orConds) > 0 { + conditions = append(conditions, "("+strings.Join(orConds, " OR ")+")") + } + } else if strVal, ok := v.(string); ok { + strVal = strings.ReplaceAll(strVal, "'", "''") + conditions = append(conditions, fmt.Sprintf("filter_fulltext('%s', '%s')", convertMatchingField(k), strVal)) + } + } else if listVal, isList := v.([]interface{}); isList { + // Handle IN conditions + var inVals []string + for _, item := range listVal { + if strItem, ok := item.(string); ok { + strItem = strings.ReplaceAll(strItem, "'", "''") + inVals = append(inVals, fmt.Sprintf("'%s'", strItem)) + } else { + inVals = append(inVals, fmt.Sprintf("%v", item)) + } + } + if len(inVals) > 0 { + conditions = append(conditions, fmt.Sprintf("%s IN (%s)", k, strings.Join(inVals, ", "))) + } + } else if k == "must_not" { + // Handle must_not conditions + if mustNotMap, ok := v.(map[string]interface{}); ok { + if existsVal, ok := mustNotMap["exists"]; ok { + if existsField, ok := existsVal.(string); ok { + col, colOk := tableColumns[existsField] + if colOk && strings.Contains(strings.ToLower(col.Type), "char") { + conditions = append(conditions, fmt.Sprintf(" %s!='' ", existsField)) + } else { + conditions = append(conditions, fmt.Sprintf("%s!=null", existsField)) + } + } + } + } + } else if strVal, ok := v.(string); ok { + strVal = strings.ReplaceAll(strVal, "'", "''") + conditions = append(conditions, fmt.Sprintf("%s='%s'", k, strVal)) + } else if k == "exists" { + if existsField, ok := v.(string); ok { + col, colOk := tableColumns[existsField] + if colOk && strings.Contains(strings.ToLower(col.Type), "char") { + conditions = append(conditions, fmt.Sprintf(" %s!='' ", existsField)) + } else { + conditions = append(conditions, fmt.Sprintf("%s!=null", existsField)) + } + } + } else { + conditions = append(conditions, fmt.Sprintf("%s=%v", k, v)) + } + } + + if len(conditions) == 0 { + return "" + } + return strings.Join(conditions, " AND ") +} + // SearchRequest Infinity search request (legacy, kept for backward compatibility) type SearchRequest struct { TableName string @@ -35,6 +161,7 @@ type SearchRequest struct { Offset int Limit int Filter map[string]interface{} + OrderBy *OrderByExpr } // SearchResponse Infinity search response @@ -69,43 +196,175 @@ type FusionExpr struct { FusionParams map[string]interface{} } -// Search executes search (supports both unified engine.SearchRequest and legacy SearchRequest) +// Search executes search (supports unified engine.SearchRequest only) func (e *infinityEngine) Search(ctx context.Context, req interface{}) (interface{}, error) { switch searchReq := req.(type) { case *types.SearchRequest: return e.searchUnified(ctx, searchReq) - case *SearchRequest: - return e.searchLegacy(ctx, searchReq) default: return nil, fmt.Errorf("invalid search request type: %T", req) } } +// convertSelectFields converts field names to Infinity format +func convertSelectFields(output []string) []string { + fieldMapping := map[string]string{ + "docnm_kwd": "docnm", + "title_tks": "docnm", + "title_sm_tks": "docnm", + "important_kwd": "important_keywords", + "important_tks": "important_keywords", + "question_kwd": "questions", + "question_tks": "questions", + "content_with_weight": "content", + "content_ltks": "content", + "content_sm_ltks": "content", + "authors_tks": "authors", + "authors_sm_tks": "authors", + } + + needEmptyCount := false + for i, field := range output { + if field == "important_kwd" { + needEmptyCount = true + } + if newField, ok := fieldMapping[field]; ok { + output[i] = newField + } + } + + // Remove duplicates + seen := make(map[string]bool) + result := []string{} + for _, f := range output { + if f != "" && !seen[f] { + seen[f] = true + result = append(result, f) + } + } + + // Add id and empty count if needed + hasID := false + for _, f := range result { + if f == "id" { + hasID = true + break + } + } + if !hasID { + result = append([]string{"id"}, result...) + } + + if needEmptyCount { + result = append(result, "important_kwd_empty_count") + } + + return result +} + +// isChinese checks if a string contains Chinese characters +func isChinese(s string) bool { + for _, r := range s { + if '\u4e00' <= r && r <= '\u9fff' { + return true + } + } + return false +} + +// hasSubTokens checks if the text has sub-tokens after fine-grained tokenization +// - Returns False if len < 3 +// - Returns False if text is only ASCII alphanumeric +// - Returns True otherwise (meaning there are sub-tokens) +func hasSubTokens(s string) bool { + if utf8.RuneCountInString(s) < 3 { + return false + } + isASCIIOnly := true + for _, r := range s { + if r > 127 { + isASCIIOnly = false + break + } + } + if isASCIIOnly { + // Check if it's only alphanumeric and allowed special chars + for _, r := range s { + if !((r >= '0' && r <= '9') || (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || r == '.' || r == '+' || r == '#' || r == '_' || r == '*' || r == '-') { + isASCIIOnly = false + break + } + } + if isASCIIOnly { + return false + } + } + // Has sub-tokens if it's Chinese and length >= 3 + return isChinese(s) +} + +// formatQuestion formats the question +// - If len < 3: returns ((query)^1.0) +// - If has sub-tokens: adds fuzzy search ((query OR "query" OR ("query"~2)^0.5)^1.0) +// - Otherwise: returns ((query)^1.0) +func formatQuestion(question string) string { + // Trim whitespace + question = strings.TrimSpace(question) + fmt.Printf("[DEBUG formatQuestion] input: %q, len: %d, hasSubTokens: %v\n", question, len(question), hasSubTokens(question)) + + // If no sub-tokens, use simple format + if !hasSubTokens(question) { + result := fmt.Sprintf("((%s)^1.0)", question) + fmt.Printf("[DEBUG formatQuestion] simple: %s\n", result) + return result + } + + result := fmt.Sprintf("((%s OR \"%s\" OR (\"%s\"~2)^0.5)^1.0)", question, question, question) + fmt.Printf("[DEBUG formatQuestion] fuzzy: %s\n", result) + return result +} + +// convertMatchingField converts field names for matching +func convertMatchingField(fieldWeightStr string) string { + // Split on ^ to get field name + parts := strings.Split(fieldWeightStr, "^") + field := parts[0] + + // Field name conversion + fieldMapping := map[string]string{ + "docnm_kwd": "docnm@ft_docnm_rag_coarse", + "title_tks": "docnm@ft_docnm_rag_coarse", + "title_sm_tks": "docnm@ft_docnm_rag_fine", + "important_kwd": "important_keywords@ft_important_keywords_rag_coarse", + "important_tks": "important_keywords@ft_important_keywords_rag_fine", + "question_kwd": "questions@ft_questions_rag_coarse", + "question_tks": "questions@ft_questions_rag_fine", + "content_with_weight": "content@ft_content_rag_coarse", + "content_ltks": "content@ft_content_rag_coarse", + "content_sm_ltks": "content@ft_content_rag_fine", + "authors_tks": "authors@ft_authors_rag_coarse", + "authors_sm_tks": "authors@ft_authors_rag_fine", + } + + if newField, ok := fieldMapping[field]; ok { + parts[0] = newField + } + + return strings.Join(parts, "^") +} + // searchUnified handles the unified engine.SearchRequest func (e *infinityEngine) searchUnified(ctx context.Context, req *types.SearchRequest) (*types.SearchResponse, error) { if len(req.IndexNames) == 0 { return nil, fmt.Errorf("index names cannot be empty") } - // For Infinity, we use the first index name as table name - tableName := req.IndexNames[0] - // Get retrieval parameters with defaults - similarityThreshold := req.SimilarityThreshold - if similarityThreshold <= 0 { - similarityThreshold = 0.1 - } - topK := req.TopK if topK <= 0 { topK = 1024 } - vectorSimilarityWeight := req.VectorSimilarityWeight - if vectorSimilarityWeight < 0 || vectorSimilarityWeight > 1 { - vectorSimilarityWeight = 0.3 - } - pageSize := req.Size if pageSize <= 0 { pageSize = 30 @@ -116,90 +375,546 @@ func (e *infinityEngine) searchUnified(ctx context.Context, req *types.SearchReq offset = 0 } - // Build search request - searchReq := &SearchRequest{ - TableName: tableName, - Limit: pageSize, - Offset: offset, - Filter: buildInfinityFilters(req.KbIDs, req.DocIDs), + // Get database + db, err := e.client.conn.GetDatabase(e.client.dbName) + if err != nil { + return nil, fmt.Errorf("failed to get database: %w", err) } - // Add text match (question is always required) - searchReq.MatchText = &MatchTextExpr{ - Fields: []string{"title_tks", "content_ltks"}, - MatchingText: req.Question, - TopN: topK, + // Build output columns + // Include all fields needed for retrieval test results + outputColumns := []string{ + "id", + "doc_id", + "kb_id", + "content", + "content_ltks", + "content_with_weight", + "title_tks", + "docnm_kwd", + "img_id", + "available_int", + "important_kwd", + "position_int", + "page_num_int", + "doc_type_kwd", + "mom_id", + "question_tks", + } + outputColumns = convertSelectFields(outputColumns) + + // Determine if text or vector search + hasTextMatch := req.Question != "" + hasVectorMatch := !req.KeywordOnly && len(req.Vector) > 0 + + // Determine score column + scoreColumn := "" + if hasTextMatch { + scoreColumn = "SCORE" + } else if hasVectorMatch { + scoreColumn = "SIMILARITY" } - // Add vector match if vector is provided and not keyword-only mode - if !req.KeywordOnly && len(req.Vector) > 0 { - fieldName := buildInfinityVectorFieldName(req.Vector) - searchReq.MatchDense = &MatchDenseExpr{ - VectorColumnName: fieldName, - EmbeddingData: req.Vector, - EmbeddingDataType: "float", - DistanceType: "cosine", - TopN: topK, - ExtraOptions: map[string]interface{}{ - "similarity": similarityThreshold, - }, - } - // Infinity uses weighted_sum fusion with weights - searchReq.Fusion = &FusionExpr{ - Method: "weighted_sum", - TopN: topK, - Weights: []float64{ - 1.0 - vectorSimilarityWeight, // text weight - vectorSimilarityWeight, // vector weight - }, + // Add score column if needed + if hasTextMatch || hasVectorMatch { + if hasTextMatch { + outputColumns = append(outputColumns, "score()") + } else if hasVectorMatch { + outputColumns = append(outputColumns, "similarity()") } + // Add pagerank field + outputColumns = append(outputColumns, PAGERANK_FLD) } - // Execute the actual search (would call Infinity SDK here) - // For now, return not implemented - return nil, fmt.Errorf("infinity search unified not implemented: waiting for official Go SDK") -} + // Remove duplicates + outputColumns = convertSelectFields(outputColumns) -// searchLegacy handles the legacy infinity.SearchRequest (backward compatibility) -func (e *infinityEngine) searchLegacy(ctx context.Context, req *SearchRequest) (*SearchResponse, error) { - // This would contain the actual Infinity search implementation - return nil, fmt.Errorf("infinity search legacy not implemented: waiting for official Go SDK") -} - -// buildInfinityFilters builds filter conditions for Infinity -func buildInfinityFilters(kbIDs []string, docIDs []string) map[string]interface{} { - filters := make(map[string]interface{}) - - // kb_id filter - if len(kbIDs) > 0 { - if len(kbIDs) == 1 { - filters["kb_id"] = kbIDs[0] + // Build filter string + var filterParts []string + if len(req.DocIDs) > 0 { + if len(req.DocIDs) == 1 { + filterParts = append(filterParts, fmt.Sprintf("doc_id = '%s'", req.DocIDs[0])) } else { - filters["kb_id"] = kbIDs + docIDs := strings.Join(req.DocIDs, "', '") + filterParts = append(filterParts, fmt.Sprintf("doc_id IN ('%s')", docIDs)) + } + } + // Default filter for available chunks + filterParts = append(filterParts, "available_int=1") + + filterStr := strings.Join(filterParts, " AND ") + + // Build order_by + var orderBy *OrderByExpr + if req.OrderBy != "" { + orderBy = &OrderByExpr{Fields: []OrderByField{}} + // Parse order_by field and direction + fields := strings.Split(req.OrderBy, ",") + for _, field := range fields { + field = strings.TrimSpace(field) + if strings.HasSuffix(field, " desc") || strings.HasSuffix(field, " DESC") { + fieldName := strings.TrimSuffix(field, " desc") + fieldName = strings.TrimSuffix(fieldName, " DESC") + orderBy.Fields = append(orderBy.Fields, OrderByField{Field: fieldName, Type: SortDesc}) + } else { + orderBy.Fields = append(orderBy.Fields, OrderByField{Field: field, Type: SortAsc}) + } } } - // doc_id filter - if len(docIDs) > 0 { - if len(docIDs) == 1 { - filters["doc_id"] = docIDs[0] + // rank_feature support + var rankFeature map[string]float64 + if req.RankFeature != nil { + rankFeature = req.RankFeature + } + + // Results from all tables + var allResults []map[string]interface{} + totalHits := int64(0) + + // Search across all tables + for _, indexName := range req.IndexNames { + // Determine table names to search + var tableNames []string + if strings.HasPrefix(indexName, "ragflow_doc_meta_") { + tableNames = []string{indexName} } else { - filters["doc_id"] = docIDs + // For each KB ID, create a table name + kbIDs := req.KbIDs + if len(kbIDs) == 0 { + // If no KB IDs, use the index name directly + kbIDs = []string{""} + } + for _, kbID := range kbIDs { + if kbID == "" { + tableNames = append(tableNames, indexName) + } else { + tableNames = append(tableNames, fmt.Sprintf("%s_%s", indexName, kbID)) + } + } + } + + // Search each table + // 1. First try with min_match=0.3 (30%) + // 2. If no results and has doc_id filter: search without match + // 3. If no results and no doc_id filter: retry with min_match=0.1 (10%) and lower similarity + minMatch := 0.3 + hasDocIDFilter := len(req.DocIDs) > 0 + + for _, tableName := range tableNames { + fmt.Printf("[DEBUG] Searching table: %s\n", tableName) + // Try to get table + _, err := db.GetTable(tableName) + if err != nil { + // Table doesn't exist, skip + continue + } + + // Build query for this table + result, err := e.executeTableSearch(db, tableName, outputColumns, req.Question, req.Vector, filterStr, topK, pageSize, offset, orderBy, rankFeature, req.SimilarityThreshold, minMatch) + if err != nil { + // Skip this table on error + continue + } + + allResults = append(allResults, result.Chunks...) + totalHits += result.Total + } + + // If no results, try fallback strategies + if totalHits == 0 && (hasTextMatch || hasVectorMatch) { + fmt.Printf("[DEBUG] No results, trying fallback strategies\n") + allResults = nil + totalHits = 0 + + if hasDocIDFilter { + // If has doc_id filter, search without match + fmt.Printf("[DEBUG] Retry with no match (has doc_id filter)\n") + for _, tableName := range tableNames { + _, err := db.GetTable(tableName) + if err != nil { + continue + } + // Search without match - pass empty question + result, err := e.executeTableSearch(db, tableName, outputColumns, "", req.Vector, filterStr, topK, pageSize, offset, orderBy, rankFeature, req.SimilarityThreshold, 0.0) + if err != nil { + continue + } + allResults = append(allResults, result.Chunks...) + totalHits += result.Total + } + } else { + // Retry with lower min_match and similarity + fmt.Printf("[DEBUG] Retry with min_match=0.1, similarity=0.17\n") + lowerThreshold := 0.17 + for _, tableName := range tableNames { + _, err := db.GetTable(tableName) + if err != nil { + continue + } + result, err := e.executeTableSearch(db, tableName, outputColumns, req.Question, req.Vector, filterStr, topK, pageSize, offset, orderBy, rankFeature, lowerThreshold, 0.1) + if err != nil { + continue + } + allResults = append(allResults, result.Chunks...) + totalHits += result.Total + } + } } } - // available_int filter (default to 1 for available chunks) - filters["available_int"] = 1 + if hasTextMatch || hasVectorMatch { + allResults = calculateScores(allResults, scoreColumn, PAGERANK_FLD) + } - return filters + if hasTextMatch || hasVectorMatch { + allResults = sortByScore(allResults, len(allResults)) + } + + // Apply threshold filter to combined results + fmt.Printf("[DEBUG] Threshold check: SimilarityThreshold=%f, hasVectorMatch=%v, hasTextMatch=%v\n", req.SimilarityThreshold, hasVectorMatch, hasTextMatch) + if req.SimilarityThreshold > 0 && hasVectorMatch { + var filteredResults []map[string]interface{} + for _, chunk := range allResults { + score := getScore(chunk) + chunkID := "" + if id, ok := chunk["id"]; ok { + chunkID = fmt.Sprintf("%v", id) + } + fmt.Printf("[DEBUG] Threshold filter: id=%s, score=%f, threshold=%f, pass=%v\n", chunkID, score, req.SimilarityThreshold, score >= req.SimilarityThreshold) + if score >= req.SimilarityThreshold { + filteredResults = append(filteredResults, chunk) + } + } + fmt.Printf("[DEBUG] After threshold filter (combined): %d -> %d chunks\n", len(allResults), len(filteredResults)) + allResults = filteredResults + } + + // Limit to pageSize + if len(allResults) > pageSize { + allResults = allResults[:pageSize] + } + + return &types.SearchResponse{ + Chunks: allResults, + Total: totalHits, + }, nil } -// buildInfinityVectorFieldName builds vector field name based on dimension -func buildInfinityVectorFieldName(vector []float64) string { - dimension := len(vector) - var fieldBuilder strings.Builder - fieldBuilder.WriteString("q_") - fieldBuilder.WriteString(strconv.Itoa(dimension)) - fieldBuilder.WriteString("_vec") - return fieldBuilder.String() +// calculateScores calculates _score = score_column + pagerank +func calculateScores(chunks []map[string]interface{}, scoreColumn, pagerankField string) []map[string]interface{} { + fmt.Printf("[DEBUG] calculateScores: scoreColumn=%s, pagerankField=%s\n", scoreColumn, pagerankField) + for i := range chunks { + score := 0.0 + if scoreVal, ok := chunks[i][scoreColumn]; ok { + if f, ok := toFloat64(scoreVal); ok { + score += f + fmt.Printf("[DEBUG] chunk[%d]: %s=%f\n", i, scoreColumn, f) + } + } + if pagerankVal, ok := chunks[i][pagerankField]; ok { + if f, ok := toFloat64(pagerankVal); ok { + score += f + } + } + chunks[i]["_score"] = score + fmt.Printf("[DEBUG] chunk[%d]: _score=%f\n", i, score) + } + return chunks +} + +// sortByScore sorts by _score descending and limits +func sortByScore(chunks []map[string]interface{}, limit int) []map[string]interface{} { + if len(chunks) == 0 { + return chunks + } + + // Sort by _score descending + for i := 0; i < len(chunks)-1; i++ { + for j := i + 1; j < len(chunks); j++ { + scoreI := getScore(chunks[i]) + scoreJ := getScore(chunks[j]) + if scoreI < scoreJ { + chunks[i], chunks[j] = chunks[j], chunks[i] + } + } + } + + // Limit + if len(chunks) > limit && limit > 0 { + chunks = chunks[:limit] + } + + return chunks +} + +func getScore(chunk map[string]interface{}) float64 { + // Check _score first + if score, ok := chunk["_score"].(float64); ok { + return score + } + if score, ok := chunk["_score"].(int); ok { + return float64(score) + } + if score, ok := chunk["_score"].(int64); ok { + return float64(score) + } + // Fallback to SCORE (for fusion) or SIMILARITY (for vector-only) + if score, ok := chunk["SCORE"].(float64); ok { + return score + } + if score, ok := chunk["SIMILARITY"].(float64); ok { + return score + } + return 0.0 +} + +func toFloat64(val interface{}) (float64, bool) { + switch v := val.(type) { + case float64: + return v, true + case float32: + return float64(v), true + case int: + return float64(v), true + case int64: + return float64(v), true + case string: + f, err := strconv.ParseFloat(v, 64) + if err != nil { + return 0, false + } + return f, true + default: + return 0, false + } +} + +// executeTableSearch executes search on a single table +func (e *infinityEngine) executeTableSearch(db *infinity.Database, tableName string, outputColumns []string, question string, vector []float64, filterStr string, topK, pageSize, offset int, orderBy *OrderByExpr, rankFeature map[string]float64, similarityThreshold float64, minMatch float64) (*types.SearchResponse, error) { + // Debug logging + fmt.Printf("[DEBUG] executeTableSearch: question=%s, topK=%d, pageSize=%d, similarityThreshold=%f, rankFeature=%v\n", question, topK, pageSize, similarityThreshold, rankFeature) + + // Get table + table, err := db.GetTable(tableName) + if err != nil { + return nil, err + } + + // Build query using Table's chainable methods + hasTextMatch := question != "" + hasVectorMatch := len(vector) > 0 + + table = table.Output(outputColumns) + + // Define text fields + textFields := []string{ + "title_tks^10", + "title_sm_tks^5", + "important_kwd^30", + "important_tks^20", + "question_tks^20", + "content_ltks^2", + "content_sm_ltks", + } + + // Convert field names for Infinity + var convertedFields []string + for _, f := range textFields { + cf := convertMatchingField(f) + convertedFields = append(convertedFields, cf) + } + fields := strings.Join(convertedFields, ",") + + // Format question + formattedQuestion := formatQuestion(question) + + // Compute full filter with filter_fulltext for MatchDense extra_options + var fullFilterWithFulltext string + if filterStr != "" && fields != "" { + fullFilterWithFulltext = fmt.Sprintf("(%s) AND FILTER_FULLTEXT('%s', '%s')", filterStr, fields, formattedQuestion) + } + + // Add text match if question is provided + if hasTextMatch { + extraOptions := map[string]string{ + "topn": fmt.Sprintf("%d", topK), + "minimum_should_match": fmt.Sprintf("%d%%", int(minMatch*100)), + } + + // Add rank_features support + if rankFeature != nil { + var rankFeaturesList []string + for featureName, weight := range rankFeature { + rankFeaturesList = append(rankFeaturesList, fmt.Sprintf("%s^%s^%f", TAG_FLD, featureName, weight)) + } + if len(rankFeaturesList) > 0 { + extraOptions["rank_features"] = strings.Join(rankFeaturesList, ",") + } + } + + table = table.MatchText(fields, formattedQuestion, topK, extraOptions) + fmt.Printf("[DEBUG] MatchTextExpr: fields=%s, matching_text=%s, topn=%d, extra_options=%v\n", fields, formattedQuestion, topK, extraOptions) + } + + // Add vector match if provided + if hasVectorMatch { + vectorSize := len(vector) + fieldName := fmt.Sprintf("q_%d_vec", vectorSize) + threshold := similarityThreshold + if threshold <= 0 { + threshold = 0.1 // default + } + extraOptions := map[string]string{ + // Add threshold + "threshold": fmt.Sprintf("%f", threshold), + } + + // Add filter with filter_fulltext, add to MatchDense extra_options + // This is the full filter that includes both available_int=1 AND filter_fulltext + if fullFilterWithFulltext != "" { + extraOptions["filter"] = fullFilterWithFulltext + fmt.Printf("[DEBUG] filterStr=%s, fullFilterWithFulltext=%s\n", filterStr, fullFilterWithFulltext) + } + + fmt.Printf("[DEBUG] MatchDenseExpr: field=%s, topn=%d, extra_options=%v\n", fieldName, topK, extraOptions) + + table = table.MatchDense(fieldName, vector, "float", "cosine", topK, extraOptions) + } + + // Add fusion (for text+vector combination) + if hasTextMatch && hasVectorMatch { + fusionParams := map[string]interface{}{ + "normalize": "atan", + "weights": "0.05,0.95", + } + fmt.Printf("[DEBUG] FusionExpr: method=weighted_sum, topn=%d, fusion_params=%v\n", topK, fusionParams) + fmt.Printf("[DEBUG] Before Fusion - table has MatchText=%v, MatchDense=%v\n", hasTextMatch, hasVectorMatch) + table = table.Fusion("weighted_sum", topK, fusionParams) + } + + // Add order_by if provided + if orderBy != nil && len(orderBy.Fields) > 0 { + var sortFields [][2]interface{} + for _, field := range orderBy.Fields { + sortType := infinity.SortTypeAsc + if field.Type == SortDesc { + sortType = infinity.SortTypeDesc + } + sortFields = append(sortFields, [2]interface{}{field.Field, sortType}) + } + table = table.Sort(sortFields) + } + + // Set limit and offset + // Use topK to get more results from Infinity, then filter/sort in Go + table = table.Limit(topK) + if offset > 0 { + table = table.Offset(offset) + } + + // Execute query - get the raw query and execute via SDK + result, err := e.executeQuery(table) + if err != nil { + return nil, err + } + + // Debug logging - show returned chunks + scoreColumn := "SIMILARITY" + if hasTextMatch { + scoreColumn = "SCORE" + } + fmt.Printf("[DEBUG] executeTableSearch returned %d chunks\n", len(result.Chunks)) + + result.Chunks = calculateScores(result.Chunks, scoreColumn, PAGERANK_FLD) + + // Debug after calculateScores + for i, chunk := range result.Chunks { + chunkID := "" + if id, ok := chunk["id"]; ok { + chunkID = fmt.Sprintf("%v", id) + } + score := getScore(chunk) + fmt.Printf("[DEBUG] chunk[%d]: id=%s, _score=%f\n", i, chunkID, score) + } + + // Sort by score + result.Chunks = sortByScore(result.Chunks, len(result.Chunks)) + + if len(result.Chunks) > pageSize { + result.Chunks = result.Chunks[:pageSize] + } + result.Total = int64(len(result.Chunks)) + + return result, nil +} + +// executeQuery executes the query and returns results +func (e *infinityEngine) executeQuery(table *infinity.Table) (*types.SearchResponse, error) { + // Use ToResult() to execute query + result, err := table.ToResult() + if err != nil { + return nil, fmt.Errorf("Infinity query failed: %w", err) + } + + // Debug: print raw result info + // fmt.Printf("[DEBUG] Infinity raw result: %+v\n", result) + + // Convert result to SearchResponse format + // The SDK returns QueryResult with Data as map[string][]interface{} + qr, ok := result.(*infinity.QueryResult) + if !ok { + return &types.SearchResponse{ + Chunks: []map[string]interface{}{}, + Total: 0, + }, nil + } + + // Convert to chunks format + chunks := make([]map[string]interface{}, 0) + for colName, colData := range qr.Data { + for i, val := range colData { + // Ensure we have a row for this index + for len(chunks) <= i { + chunks = append(chunks, make(map[string]interface{})) + } + chunks[i][colName] = val + } + } + + // Post-process: convert nil/empty values to empty slices for array-like fields + arrayFields := map[string]bool{ + "doc_type_kwd": true, + "important_kwd": true, + "important_tks": true, + "question_tks": true, + "authors_tks": true, + "authors_sm_tks": true, + "title_tks": true, + "title_sm_tks": true, + "content_ltks": true, + "content_sm_ltks": true, + } + for i := range chunks { + for colName := range arrayFields { + if val, ok := chunks[i][colName]; !ok || val == nil || val == "" { + chunks[i][colName] = []interface{}{} + } + } + } + + return &types.SearchResponse{ + Chunks: chunks, + Total: int64(len(chunks)), + }, nil +} + +// contains checks if slice contains string +func contains(slice []string, item string) bool { + for _, s := range slice { + if s == item { + return true + } + } + return false } diff --git a/internal/engine/types/types.go b/internal/engine/types/types.go index e1ebfc4ab..a7990f9c4 100644 --- a/internal/engine/types/types.go +++ b/internal/engine/types/types.go @@ -43,6 +43,10 @@ type SearchRequest struct { SimilarityThreshold float64 // Minimum similarity score (default: 0.1) VectorSimilarityWeight float64 // Weight for vector vs keyword (default: 0.3) + // Sorting and ranking + OrderBy string // Order by field (e.g., "field1 desc, field2 asc") + RankFeature map[string]float64 // Rank features for learning to rank + // Engine-specific options (optional, for advanced use) Options map[string]interface{} } diff --git a/internal/server/config.go b/internal/server/config.go index 111dec213..6bbd87597 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -414,7 +414,11 @@ func Init(configPath string) error { // Map doc_engine section to DocEngineConfig if globalConfig != nil && globalConfig.DocEngine.Type == "" { - // Try to map from doc_engine section + // Use DOC_ENGINE env var if set + if docEngine != "" { + globalConfig.DocEngine.Type = EngineType(docEngine) + } + // Try to map from doc_engine section (overrides env var if present) if v.IsSet("doc_engine") { docEngineConfig := v.Sub("doc_engine") if docEngineConfig != nil { diff --git a/internal/service/chunk.go b/internal/service/chunk.go index cbed1665d..89b06fa86 100644 --- a/internal/service/chunk.go +++ b/internal/service/chunk.go @@ -20,6 +20,8 @@ import ( "context" "fmt" "ragflow/internal/server" + "strconv" + "strings" "go.uber.org/zap" @@ -348,10 +350,10 @@ func getSimilarityThreshold(threshold *float64) float64 { } func getVectorSimilarityWeight(weight *float64) float64 { - //if weight != nil && *weight >= 0 && *weight <= 1 { - // return *weight - //} - return 0.95 + if weight != nil && *weight >= 0 && *weight <= 1 { + return *weight + } + return 0.3 } func buildIndexNames(tenantIDs []string) []string { @@ -424,19 +426,28 @@ func buildRetrievalTestResults(filteredChunks []map[string]interface{}) []map[st result := make(map[string]interface{}) // Key mappings - if v, ok := chunk["_id"]; ok { + if v, ok := chunk["id"]; ok { + result["chunk_id"] = v + } else if v, ok := chunk["_id"]; ok { result["chunk_id"] = v } - if v, ok := chunk["content_ltks"]; ok { + if v, ok := chunk["content"]; ok { result["content_ltks"] = v - } - if v, ok := chunk["content_with_weight"]; ok { result["content_with_weight"] = v + } else { + if v, ok := chunk["content_ltks"]; ok { + result["content_ltks"] = v + } + if v, ok := chunk["content_with_weight"]; ok { + result["content_with_weight"] = v + } } if v, ok := chunk["doc_id"]; ok { result["doc_id"] = v } - if v, ok := chunk["docnm_kwd"]; ok { + if v, ok := chunk["docnm"]; ok { + result["docnm_kwd"] = v + } else if v, ok := chunk["docnm_kwd"]; ok { result["docnm_kwd"] = v } if v, ok := chunk["img_id"]; ok { @@ -446,7 +457,22 @@ func buildRetrievalTestResults(filteredChunks []map[string]interface{}) []map[st result["kb_id"] = v } if v, ok := chunk["position_int"]; ok { - result["positions"] = v + if strVal, ok := v.(string); ok && strVal != "" { + result["positions"] = convertPositionInt(strVal) + } else { + result["positions"] = []interface{}{} + } + } + if v, ok := chunk["doc_type_kwd"]; ok { + result["doc_type_kwd"] = v + } + if v, ok := chunk["mom_id"]; ok { + result["mom_id"] = v + } + if v, ok := chunk["important_kwd"]; ok { + result["important_kwd"] = v + } else if v, ok := chunk["important_keywords"]; ok { + result["important_kwd"] = v } if v, ok := chunk["similarity"]; ok { result["similarity"] = v @@ -463,3 +489,43 @@ func buildRetrievalTestResults(filteredChunks []map[string]interface{}) []map[st return results } + +// convertPositionInt converts hex string format "00000001_0000005e_..." to array [[1, 94, ...], ...] +func convertPositionInt(hexStr string) []interface{} { + if hexStr == "" { + return []interface{}{} + } + + parts := strings.Split(hexStr, "_") + var intVals []int + for _, part := range parts { + if part == "" { + continue + } + // Parse hex string (without 0x prefix) + val, err := strconv.ParseInt(part, 16, 64) + if err != nil { + continue + } + intVals = append(intVals, int(val)) + } + + // Group by 5 elements + var result []interface{} + for i := 0; i < len(intVals); i += 5 { + end := i + 5 + if end > len(intVals) { + end = len(intVals) + } + group := make([]int, end-i) + copy(group, intVals[i:end]) + // Convert to interface{} for JSON serialization + groupIf := make([]interface{}, len(group)) + for j, v := range group { + groupIf[j] = v + } + result = append(result, groupIf) + } + + return result +} diff --git a/internal/service/nlp/reranker.go b/internal/service/nlp/reranker.go index 17699a43d..7ac1a2a31 100644 --- a/internal/service/nlp/reranker.go +++ b/internal/service/nlp/reranker.go @@ -74,7 +74,12 @@ func Rerank( if useInfinity { // For Infinity: scores are already normalized before fusion // Just extract the scores from results - return RerankInfinityFallback(sres) + // Check if there are results to rerank + if resp == nil || resp.Total == 0 || len(resp.Chunks) == 0 { + return []float64{}, []float64{}, []float64{} + } + + return RerankInfinityFallback(resp) } // For Elasticsearch: need to perform reranking @@ -208,18 +213,26 @@ func RerankStandard( return HybridSimilarity(questionVector, insEmbd, keywords, insTw, tkWeight, vtWeight, qb) } -// RerankInfinityFallback extracts scores from Infinity search results -// Infinity normalizes each way score before fusion, so we just extract them -func RerankInfinityFallback(sres *SearchResult) (sim []float64, tsim []float64, vsim []float64) { - sim = make([]float64, len(sres.IDs)) - for i, id := range sres.IDs { - if fields := sres.Field[id]; fields != nil { - if score, ok := fields["_score"].(float64); ok { +// RerankInfinityFallback is used as a fallback when no reranker model is provided for Infinity engine. +// Infinity can return scores in various field names (SCORE, score, SIMILARITY, etc.), +// so we check multiple possible field names. If no score is found, we default to 1.0 +// to ensure the chunk passes through any similarity threshold filters. +func RerankInfinityFallback(resp *engine.SearchResponse) (sim []float64, tsim []float64, vsim []float64) { + sim = make([]float64, len(resp.Chunks)) + for i, chunk := range resp.Chunks { + scoreFound := false + scoreFields := []string{"SCORE", "score", "SIMILARITY", "similarity", "_score", "score()", "similarity()"} + for _, field := range scoreFields { + if score, ok := chunk[field].(float64); ok { sim[i] = score + scoreFound = true + break } } + if !scoreFound { + sim[i] = 1.0 + } } - // For Infinity, tsim and vsim are the same as overall similarity return sim, sim, sim }