Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
agentchat
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李伟@五瓣科技
agentchat
Commits
c8150637
Commit
c8150637
authored
May 29, 2025
by
Wade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
milvus write ok
parent
d7a0aa40
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
743 additions
and
64 deletions
+743
-64
milvus.go
plugins/milvus/milvus.go
+518
-55
milvus_test.go
plugins/milvus/milvus_test.go
+225
-9
No files found.
plugins/milvus/milvus.go
View file @
c8150637
This diff is collapsed.
Click to expand it.
plugins/milvus/milvus_test.go
View file @
c8150637
...
@@ -66,16 +66,22 @@ func dropCollection(ctx context.Context, client client.Client, collectionName st
...
@@ -66,16 +66,22 @@ func dropCollection(ctx context.Context, client client.Client, collectionName st
func
TestMilvusIntegration
(
t
*
testing
.
T
)
{
func
TestMilvusIntegration
(
t
*
testing
.
T
)
{
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
// Initialize Genkit
g
:=
&
genkit
.
Genkit
{}
// Initialize Milvus plugin
// Initialize Milvus plugin
m
:=
&
Milvus
{
m
s
:=
Milvus
{
Addr
:
"54.92.111.204:19530"
,
// Milvus gRPC endpoint
Addr
:
"54.92.111.204:19530"
,
// Milvus gRPC endpoint
}
}
err
:=
m
.
Init
(
ctx
,
g
)
// Initialize Genkit with Milvus plugin
g
,
err
:=
genkit
.
Init
(
ctx
,
genkit
.
WithPlugins
(
&
ms
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Milvus.Init failed: %v"
,
err
)
t
.
Fatalf
(
"genkit.Init failed: %v"
,
err
)
}
// Get the Milvus client for cleanup
m
,
ok
:=
genkit
.
LookupPlugin
(
g
,
provider
)
.
(
*
Milvus
)
if
!
ok
{
t
.
Fatalf
(
"Failed to lookup Milvus plugin"
)
}
}
defer
m
.
client
.
Close
()
defer
m
.
client
.
Close
()
...
@@ -87,7 +93,7 @@ func TestMilvusIntegration(t *testing.T) {
...
@@ -87,7 +93,7 @@ func TestMilvusIntegration(t *testing.T) {
Collection
:
collectionName
,
Collection
:
collectionName
,
Dimension
:
768
,
// Match mock embedder dimension
Dimension
:
768
,
// Match mock embedder dimension
Embedder
:
&
MockEmbedder
{},
Embedder
:
&
MockEmbedder
{},
EmbedderOptions
:
map
[
string
]
interface
{}{},
EmbedderOptions
:
map
[
string
]
interface
{}{},
// Explicitly set as map
}
}
// Define indexer and retriever
// Define indexer and retriever
...
@@ -116,7 +122,7 @@ func TestMilvusIntegration(t *testing.T) {
...
@@ -116,7 +122,7 @@ func TestMilvusIntegration(t *testing.T) {
},
},
}
}
req
:=
&
ai
.
IndexerRequest
{
Documents
:
documents
}
req
:=
&
ai
.
IndexerRequest
{
Documents
:
documents
}
err
=
indexer
.
Index
(
ctx
,
req
)
err
:
=
indexer
.
Index
(
ctx
,
req
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"Index failed: %v"
,
err
)
t
.
Fatalf
(
"Index failed: %v"
,
err
)
}
}
...
@@ -152,7 +158,7 @@ func TestMilvusIntegration(t *testing.T) {
...
@@ -152,7 +158,7 @@ func TestMilvusIntegration(t *testing.T) {
t
.
Run
(
"Empty Index"
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
"Empty Index"
,
func
(
t
*
testing
.
T
)
{
req
:=
&
ai
.
IndexerRequest
{
Documents
:
[]
*
ai
.
Document
{}}
req
:=
&
ai
.
IndexerRequest
{
Documents
:
[]
*
ai
.
Document
{}}
err
=
indexer
.
Index
(
ctx
,
req
)
err
:
=
indexer
.
Index
(
ctx
,
req
)
assert
.
NoError
(
t
,
err
,
"Indexing empty documents should succeed"
)
assert
.
NoError
(
t
,
err
,
"Indexing empty documents should succeed"
)
})
})
...
@@ -161,9 +167,219 @@ func TestMilvusIntegration(t *testing.T) {
...
@@ -161,9 +167,219 @@ func TestMilvusIntegration(t *testing.T) {
Query
:
&
ai
.
Document
{
Content
:
[]
*
ai
.
Part
{
ai
.
NewTextPart
(
"Hello world"
)}},
Query
:
&
ai
.
Document
{
Content
:
[]
*
ai
.
Part
{
ai
.
NewTextPart
(
"Hello world"
)}},
Options
:
&
RetrieverOptions
{
MetricType
:
"INVALID"
},
Options
:
&
RetrieverOptions
{
MetricType
:
"INVALID"
},
}
}
_
,
err
=
retriever
.
Retrieve
(
ctx
,
queryReq
)
_
,
err
:
=
retriever
.
Retrieve
(
ctx
,
queryReq
)
assert
.
Error
(
t
,
err
,
"Should fail with invalid metric type"
)
assert
.
Error
(
t
,
err
,
"Should fail with invalid metric type"
)
assert
.
Contains
(
t
,
err
.
Error
(),
"unsupported metric type"
)
assert
.
Contains
(
t
,
err
.
Error
(),
"unsupported metric type"
)
})
})
t
.
Run
(
"Invalid Embedder Options"
,
func
(
t
*
testing
.
T
)
{
// Test with invalid EmbedderOptions type
invalidCfg
:=
CollectionConfig
{
Collection
:
collectionName
+
"_invalid"
,
Dimension
:
768
,
Embedder
:
&
MockEmbedder
{},
EmbedderOptions
:
"not-a-map"
,
// Invalid type
}
_
,
_
,
err
:=
DefineIndexerAndRetriever
(
ctx
,
g
,
invalidCfg
)
assert
.
Error
(
t
,
err
,
"Should fail with invalid EmbedderOptions type"
)
assert
.
Contains
(
t
,
err
.
Error
(),
"EmbedderOptions must be a map[string]interface{}"
)
})
}
}
// // Copyright 2025 Google LLC
// //
// // Licensed under the Apache License, Version 2.0 (the "License");
// // you may not use this file except in compliance with the License.
// // You may obtain a copy of the License at
// //
// // http://www.apache.org/licenses/LICENSE-2.0
// //
// // Unless required by applicable law or agreed to in writing, software
// // distributed under the License is distributed on an "AS IS" BASIS,
// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// // See the License for the specific language governing permissions and
// // limitations under the License.
// //
// // SPDX-License-Identifier: Apache-2.0
// package milvus
// import (
// "context"
// "fmt"
// "strings"
// "testing"
// "time"
// "github.com/firebase/genkit/go/ai"
// "github.com/firebase/genkit/go/genkit"
// "github.com/milvus-io/milvus-sdk-go/v2/client"
// "github.com/test-go/testify/assert"
// )
// // MockEmbedder is a mock implementation of ai.Embedder.
// type MockEmbedder struct{}
// func (m *MockEmbedder) Name() string {
// return "mock-embedder"
// }
// func (m *MockEmbedder) Embed(ctx context.Context, req *ai.EmbedRequest) (*ai.EmbedResponse, error) {
// resp := &ai.EmbedResponse{}
// for range req.Input {
// // Generate a simple embedding (768-dimensional vector of ones)
// embedding := make([]float32, 768)
// for i := range embedding {
// embedding[i] = 1.0
// }
// resp.Embeddings = append(resp.Embeddings, &ai.Embedding{Embedding: embedding})
// }
// return resp, nil
// }
// // dropCollection cleans up a test collection.
// func dropCollection(ctx context.Context, client client.Client, collectionName string) error {
// exists, err := client.HasCollection(ctx, collectionName)
// if err != nil {
// return fmt.Errorf("check collection: %w", err)
// }
// if exists {
// err = client.DropCollection(ctx, collectionName)
// if err != nil {
// return fmt.Errorf("drop collection: %w", err)
// }
// }
// return nil
// }
// func TestMilvusIntegration(t *testing.T) {
// ctx := context.Background()
// // Initialize Milvus plugin
// ms := Milvus{
// Addr: "54.92.111.204:19530", // Milvus gRPC endpoint
// }
// // Initialize Genkit with Milvus plugin
// g, err := genkit.Init(ctx, genkit.WithPlugins(&ms))
// if err != nil {
// t.Fatalf("genkit.Init failed: %v", err)
// }
// // Get the Milvus client for cleanup
// m, ok := genkit.LookupPlugin(g, provider).(*Milvus)
// if !ok {
// t.Fatalf("Failed to lookup Milvus plugin")
// }
// defer m.client.Close()
// // Generate unique collection name
// collectionName := fmt.Sprintf("test_collection_%d", time.Now().UnixNano())
// // Configure collection
// cfg := CollectionConfig{
// Collection: collectionName,
// Dimension: 768, // Match mock embedder dimension
// Embedder: &MockEmbedder{},
// EmbedderOptions: map[string]interface{}{}, // Explicitly set as map
// }
// // Define indexer and retriever
// indexer, retriever, err := DefineIndexerAndRetriever(ctx, g, cfg)
// if err != nil {
// t.Fatalf("DefineIndexerAndRetriever failed: %v", err)
// }
// // Clean up collection after test
// defer func() {
// if err := dropCollection(ctx, m.client, collectionName); err != nil {
// t.Errorf("Cleanup failed: %v", err)
// }
// }()
// t.Run("Index and Retrieve", func(t *testing.T) {
// // Index documents
// documents := []*ai.Document{
// {
// Content: []*ai.Part{ai.NewTextPart("Hello world")},
// Metadata: map[string]interface{}{"id": int64(1), "category": "greeting"},
// },
// {
// Content: []*ai.Part{ai.NewTextPart("AI is amazing")},
// Metadata: map[string]interface{}{"id": int64(2), "category": "example"},
// },
// }
// req := &ai.IndexerRequest{Documents: documents}
// err := indexer.Index(ctx, req)
// if err != nil {
// t.Fatalf("Index failed: %v", err)
// }
// // Wait briefly to ensure Milvus processes the index
// time.Sleep(1 * time.Second)
// // Retrieve documents
// queryReq := &ai.RetrieverRequest{
// Query: &ai.Document{Content: []*ai.Part{ai.NewTextPart("Hello world")}},
// Options: &RetrieverOptions{
// Count: 2,
// MetricType: "L2",
// },
// }
// resp, err := retriever.Retrieve(ctx, queryReq)
// if err != nil {
// t.Fatalf("Retrieve failed: %v", err)
// }
// // Verify results
// assert.NotNil(t, resp, "Response should not be nil")
// assert.NotEmpty(t, resp.Documents, "Should return at least one document")
// for _, doc := range resp.Documents {
// assert.NotEmpty(t, doc.Content[0].Text, "Document text should not be empty")
// // Note: Mock embedder returns identical vectors, so results may not be exact
// if strings.Contains(doc.Content[0].Text, "Hello world") || strings.Contains(doc.Content[0].Text, "AI is amazing") {
// continue
// }
// t.Errorf("Unexpected document text: %s", doc.Content[0].Text)
// }
// })
// t.Run("Empty Index", func(t *testing.T) {
// req := &ai.IndexerRequest{Documents: []*ai.Document{}}
// err := indexer.Index(ctx, req)
// assert.NoError(t, err, "Indexing empty documents should succeed")
// })
// t.Run("Invalid Retrieve Options", func(t *testing.T) {
// queryReq := &ai.RetrieverRequest{
// Query: &ai.Document{Content: []*ai.Part{ai.NewTextPart("Hello world")}},
// Options: &RetrieverOptions{MetricType: "INVALID"},
// }
// _, err := retriever.Retrieve(ctx, queryReq)
// assert.Error(t, err, "Should fail with invalid metric type")
// assert.Contains(t, err.Error(), "unsupported metric type")
// })
// t.Run("Invalid Embedder Options", func(t *testing.T) {
// // Test with invalid EmbedderOptions type
// invalidCfg := CollectionConfig{
// Collection: collectionName + "_invalid",
// Dimension: 768,
// Embedder: &MockEmbedder{},
// EmbedderOptions: "not-a-map", // Invalid type
// }
// _, _, err := DefineIndexerAndRetriever(ctx, g, invalidCfg)
// assert.Error(t, err, "Should fail with invalid EmbedderOptions type")
// assert.Contains(t, err.Error(), "EmbedderOptions must be a map[string]interface{}")
// })
// }
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment