Commit 786b69d4 authored by Wade's avatar Wade

update grap param

parent ddcc501a
......@@ -19,3 +19,12 @@ curl -X POST http://localhost:8000/indexDocuments \
curl -X POST http://localhost:8000/indexGraph \
-H "Content-Type: application/json" \
-d '{"user_id": "user456", "username": "Bob", "content": "What is the capital of UK?", "metadata": {}}'
{"result": "Document indexed successfully"}
......@@ -33,6 +33,16 @@ type Input struct {
// DocumentInput 结构体用于文档索引接口
type DocumentInput struct {
// UserID string `json:"user_id"`
// Username string `json:"username"`
Content string `json:"content"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
// GraphInput 结构体用于文档索引接口
type GraphInput struct {
UserID string `json:"user_id"`
Username string `json:"username"`
Content string `json:"content"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
......@@ -113,10 +123,26 @@ func main() {
_ = graphRetriever
genkit.DefineFlow(g, "indexGraph", func(ctx context.Context, input *DocumentInput) (string, error) {
genkit.DefineFlow(g, "indexGraph", func(ctx context.Context, input *GraphInput) (string, error) {
opt := graphrag.IndexReqOption{
UserId: input.UserID,
UserName: input.Username,
}
if _, ok := input.Metadata[graphrag.DocNameKey]; !ok {
// Generate random docName.
docName, err := graphrag.GenerateRandomDocName(8)
if err != nil {
return "", fmt.Errorf("generate random docName for document %w", err)
}
input.Metadata[graphrag.DocNameKey] = docName
}
doc := ai.DocumentFromText(input.Content, input.Metadata)
err := graphIndexer.Index(ctx, &ai.IndexerRequest{
Documents: []*ai.Document{doc},
Options: &opt,
})
if err != nil {
return "", fmt.Errorf("index document: %w", err)
......
......@@ -139,50 +139,48 @@ func (c *Client) AddDocument(spaceID string, req DocumentRequest) (*http.Respons
return resp, nil
}
// SyncDocumentsRequest defines the request body for the sync documents endpoint.
type SyncDocumentsRequest struct {
DocIDs []string `json:"doc_ids"`
DocIDs []string `json:"doc_ids"`
}
// SyncDocuments sends a POST request to sync documents for the given spaceID.
func (c *Client) SyncDocuments(spaceID string, docIDs []string) (success bool, err error) {
url := fmt.Sprintf("%s/knowledge/%s/document/sync", c.BaseURL, spaceID)
reqBody := SyncDocumentsRequest{
DocIDs: docIDs,
}
body, err := json.Marshal(reqBody)
if err != nil {
return false, fmt.Errorf("failed to marshal request: %w", err)
}
httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
if err != nil {
return false, fmt.Errorf("failed to create request: %w", err)
}
httpReq.Header.Set("Accept", "application/json")
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
if err != nil {
return false, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return false, fmt.Errorf("failed to read response body: %w", err)
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("request failed with status %d: %s", resp.StatusCode, string(respBody))
}
return success, nil
}
url := fmt.Sprintf("%s/knowledge/%s/document/sync", c.BaseURL, spaceID)
reqBody := SyncDocumentsRequest{
DocIDs: docIDs,
}
body, err := json.Marshal(reqBody)
if err != nil {
return false, fmt.Errorf("failed to marshal request: %w", err)
}
httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
if err != nil {
return false, fmt.Errorf("failed to create request: %w", err)
}
httpReq.Header.Set("Accept", "application/json")
httpReq.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(httpReq)
if err != nil {
return false, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return false, fmt.Errorf("failed to read response body: %w", err)
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("request failed with status %d: %s", resp.StatusCode, string(respBody))
}
return success, nil
}
// SyncBatchDocument 同步批量处理文档
func (c *Client) SyncBatchDocument(spaceID string, req []SyncBatchRequest) (*http.Response, error) {
......@@ -328,7 +326,7 @@ func Retriever(g *genkit.Genkit, spaceID string) ai.Retriever {
}
// generateRandomDocName generates a random alphanumeric string of the specified length.
func generateRandomDocName(length int) (string, error) {
func GenerateRandomDocName(length int) (string, error) {
const charset = "abcdefghijklmnopqrstuvwxyz0123456789"
var result strings.Builder
result.Grow(length)
......@@ -346,21 +344,26 @@ func generateRandomDocName(length int) (string, error) {
// ParseJSONResponse parses a JSON byte slice and extracts the success boolean and data fields as a string.
func ParseJSONResponse(jsonBytes []byte) (success bool, data string, err error) {
// Define struct to capture only the needed fields
type jsonResponse struct {
Success bool `json:"success"`
Data int `json:"data"` // Use string to capture JSON string data
}
var resp jsonResponse
if err := json.Unmarshal(jsonBytes, &resp); err != nil {
return false, "", fmt.Errorf("failed to unmarshal JSON: %w", err)
}
return resp.Success, fmt.Sprintf("%d",resp.Data), nil
// Define struct to capture only the needed fields
type jsonResponse struct {
Success bool `json:"success"`
Data int `json:"data"` // Use string to capture JSON string data
}
var resp jsonResponse
if err := json.Unmarshal(jsonBytes, &resp); err != nil {
return false, "", fmt.Errorf("failed to unmarshal JSON: %w", err)
}
return resp.Success, fmt.Sprintf("%d", resp.Data), nil
}
type IndexReqOption struct {
UserId string
UserName string
}
const DocNameKey = "doc_name"
// Index implements the Indexer.Index method.
func (ds *docStore) Index(ctx context.Context, req *ai.IndexerRequest) error {
......@@ -368,28 +371,27 @@ func (ds *docStore) Index(ctx context.Context, req *ai.IndexerRequest) error {
return nil
}
userid := ""
usernmae := ""
for _, doc := range req.Documents {
if v, ok := doc.Metadata["user_id"]; ok {
if str, isString := v.(string); isString {
userid = str
}
}
if v, ok := doc.Metadata["username"]; ok {
if str, isString := v.(string); isString {
usernmae = str
}
}
// Type-assert req.Options to IndexReqOption
opt, ok := req.Options.(*IndexReqOption)
if !ok {
return fmt.Errorf("invalid options type: got %T, want *IndexReqOption", req.Options)
}
// Create knowledge space.
// Validate required fields
if opt.UserId == "" {
return fmt.Errorf("UserId is required in IndexReqOption")
}
if opt.UserName == "" {
return fmt.Errorf("UserName is required in IndexReqOption")
}
// Create knowledge space
spaceReq := SpaceRequest{
Name: userid,
Name: opt.UserId,
VectorType: "KnowledgeGraph",
DomainType: "Normal",
Desc: usernmae,
Owner: userid,
Desc: opt.UserName,
Owner: opt.UserId,
}
resp, err := ds.client.AddSpace(spaceReq)
if err != nil {
......@@ -403,37 +405,25 @@ func (ds *docStore) Index(ctx context.Context, req *ai.IndexerRequest) error {
fmt.Println("space ok")
spaceId := userid
spaceId := opt.UserId
// Index each document.
// Index each document
for i, doc := range req.Documents {
// Use DocName from options, fall back to random name if empty
docName := ""
if v, ok := doc.Metadata["doc_name"]; ok {
if v, ok := doc.Metadata[DocNameKey]; ok {
if str, isString := v.(string); isString {
docName = str
} else {
// Generate random docName.
var err error
docName, err = generateRandomDocName(8)
if err != nil {
return fmt.Errorf("generate random docName for document %d: %w", i+1, err)
}
return fmt.Errorf("must provide doc_name str value in metadata")
}
} else {
// Generate random docName.
var err error
docName, err = generateRandomDocName(8)
if err != nil {
return fmt.Errorf("generate random docName for document %d: %w", i+1, err)
}
return fmt.Errorf("must provide doc_name key in metadata")
}
fmt.Println("docName: ", docName)
// Add document.
// Add document
var sb strings.Builder
for _, p := range doc.Content {
if p.IsText() {
......@@ -441,49 +431,183 @@ func (ds *docStore) Index(ctx context.Context, req *ai.IndexerRequest) error {
}
}
text := sb.String()
fmt.Println("text: ",text)
fmt.Println("text: ", text)
docReq := DocumentRequest{
DocName: docName,
Source: "api",
DocType: "TEXT",
Content: text,
Labels: "",
// Questions: []string{},
DocName: docName,
Source: "api",
DocType: "TEXT",
Content: text,
Labels: "",
Metadata: doc.Metadata,
}
resp, err := ds.client.AddDocument(spaceId, docReq)
if err != nil {
return fmt.Errorf("add document %d: %w", i+1, err)
}
body, _ := io.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
resp.Body.Close()
return fmt.Errorf("read add document response %d: %w", i+1, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("add document %d failed with status %d: %s", i+1, resp.StatusCode, string(body))
}
// Parse AddDocument response
ok, idx, err := ParseJSONResponse(body)
if err != nil {
return fmt.Errorf("ParseJSONResponse %d: %w", i+1, err)
return fmt.Errorf("parse add document response %d: %w", i+1, err)
}
if !ok{
return fmt.Errorf("ParseJSONResponse body %d: %w", i+1, err)
if !ok {
return fmt.Errorf("add document %d failed: response success=false, data=%s", i+1, idx)
}
fmt.Println("document ok",string(body),idx)
ok ,err =ds.client.SyncDocuments(spaceId,[]string{idx})
fmt.Println("document ok", string(body), idx)
if err != nil{
return err
// Sync document
syncOk, err := ds.client.SyncDocuments(spaceId, []string{idx})
if err != nil {
return fmt.Errorf("sync document %d: %w", i+1, err)
}
if syncOk {
return fmt.Errorf("sync document %d failed.", i+1, )
}
fmt.Println("sync ok", syncOk)
}
return nil
}
// type IndexReqOption struct{
// UserId string
// UserName string
// DocName string
// }
// // Index implements the Indexer.Index method.
// func (ds *docStore) Index(ctx context.Context, req *ai.IndexerRequest) error {
// if len(req.Documents) == 0 {
// return nil
// }
// req.Options
// userid := ""
// usernmae := ""
// for _, doc := range req.Documents {
// if v, ok := doc.Metadata["user_id"]; ok {
// if str, isString := v.(string); isString {
// userid = str
// }
// }
// if v, ok := doc.Metadata["username"]; ok {
// if str, isString := v.(string); isString {
// usernmae = str
// }
// }
// }
// // Create knowledge space.
// spaceReq := SpaceRequest{
// Name: userid,
// VectorType: "KnowledgeGraph",
// DomainType: "Normal",
// Desc: usernmae,
// Owner: userid,
// }
// resp, err := ds.client.AddSpace(spaceReq)
// if err != nil {
// return fmt.Errorf("add space: %w", err)
// }
// defer resp.Body.Close()
// if resp.StatusCode != http.StatusOK {
// body, _ := io.ReadAll(resp.Body)
// return fmt.Errorf("add space failed with status %d: %s", resp.StatusCode, string(body))
// }
// fmt.Println("space ok")
// spaceId := userid
// // Index each document.
// for i, doc := range req.Documents {
// docName := ""
// if v, ok := doc.Metadata["doc_name"]; ok {
// if str, isString := v.(string); isString {
// docName = str
// } else {
// // Generate random docName.
// var err error
// docName, err = generateRandomDocName(8)
// if err != nil {
// return fmt.Errorf("generate random docName for document %d: %w", i+1, err)
// }
// }
// } else {
// // Generate random docName.
// var err error
// docName, err = generateRandomDocName(8)
// if err != nil {
// return fmt.Errorf("generate random docName for document %d: %w", i+1, err)
// }
// }
// fmt.Println("docName: ", docName)
// // Add document.
// var sb strings.Builder
// for _, p := range doc.Content {
// if p.IsText() {
// sb.WriteString(p.Text)
// }
// }
// text := sb.String()
// fmt.Println("text: ",text)
// docReq := DocumentRequest{
// DocName: docName,
// Source: "api",
// DocType: "TEXT",
// Content: text,
// Labels: "",
// // Questions: []string{},
// Metadata: doc.Metadata,
// }
// resp, err := ds.client.AddDocument(spaceId, docReq)
// if err != nil {
// return fmt.Errorf("add document %d: %w", i+1, err)
// }
// body, _ := io.ReadAll(resp.Body)
// defer resp.Body.Close()
// if resp.StatusCode != http.StatusOK {
// return fmt.Errorf("add document %d failed with status %d: %s", i+1, resp.StatusCode, string(body))
// }
// ok, idx, err := ParseJSONResponse(body)
// if err != nil {
// return fmt.Errorf("ParseJSONResponse %d: %w", i+1, err)
// }
// if !ok{
// return fmt.Errorf("ParseJSONResponse body %d: %w", i+1, err)
// }
// fmt.Println("document ok",string(body),idx)
// ok ,err =ds.client.SyncDocuments(spaceId,[]string{idx})
// if err != nil{
// return err
// }
// }
// return nil
// }
// RetrieverOptions for Knowledge retrieval.
type RetrieverOptions struct {
Count int `json:"count,omitempty"` // Max documents to retrieve.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment