Remove obsolete configuration and test files for Knowledge Base

- Deleted config.go, config_test.go, types.go, and related test files to streamline the codebase and remove deprecated components.
- Refactored Knowledge Base loading logic to utilize updated configuration structures, enhancing clarity and maintainability.
- Updated references in kb.go to align with the new configuration types, ensuring compatibility with the latest changes.
This commit is contained in:
Max 2025-07-25 11:36:15 +08:00
parent bb64eef20d
commit 7fa825a334
13 changed files with 696 additions and 5 deletions

View file

@ -8,6 +8,12 @@ import (
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/kun/log"
"github.com/yaoapp/yao/config"
// Register the built-in providers
_ "github.com/yaoapp/yao/kb/providers"
// Import the kb types
kbtypes "github.com/yaoapp/yao/kb/types"
)
// Instance is the GraphRag instance
@ -15,7 +21,7 @@ var Instance types.GraphRag = nil
// KnowledgeBase is the Knowledge Base instance
type KnowledgeBase struct {
Config *Config // Knowledge Base configuration
Config *kbtypes.Config // Knowledge Base configuration
*graphrag.GraphRag
}
@ -33,7 +39,7 @@ func Load(appConfig config.Config) (*KnowledgeBase, error) {
}
// Parse the configuration
var config Config
var config kbtypes.Config
raw, err := application.App.Read(filepath.Join("kb", "kb.yao"))
if err != nil {
return nil, err

1
kb/provider.go Normal file
View file

@ -0,0 +1 @@
package kb

54
kb/providers/chunking.go Normal file
View file

@ -0,0 +1,54 @@
package providers
import (
"github.com/yaoapp/gou/graphrag/chunking"
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/yao/kb/providers/factory"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// Structured is a structured chunking provider
type Structured struct{}
// Semantic is a semantic chunking provider
type Semantic struct{}
// AutoRegister registers the chunking providers
func init() {
factory.Chunkings["__yao.structured"] = &Structured{}
factory.Chunkings["__yao.semantic"] = &Semantic{}
}
// === Structured Chunking ===
// Make creates a structured chunking provider
func (s *Structured) Make(_ *kbtypes.ProviderOption) (types.Chunking, error) {
return chunking.NewStructuredChunker(), nil
}
// Options returns the options for the structured chunking provider
func (s *Structured) Options(option *kbtypes.ProviderOption) (*types.ChunkingOptions, error) {
return nil, nil
}
// Schema returns the schema for the structured chunking provider
func (s *Structured) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Semantic Chunking ===
// Make creates a semantic chunking provider
func (s *Semantic) Make(_ *kbtypes.ProviderOption) (types.Chunking, error) {
return chunking.NewSemanticChunker(nil), nil
}
// Options returns the options for the semantic chunking provider
func (s *Semantic) Options(option *kbtypes.ProviderOption) (*types.ChunkingOptions, error) {
return nil, nil
}
// Schema returns the schema for the semantic chunking provider
func (s *Semantic) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}

251
kb/providers/converter.go Normal file
View file

@ -0,0 +1,251 @@
package providers
import (
"strings"
"github.com/yaoapp/gou/graphrag/converter"
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/yao/kb/providers/factory"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// Converter is a base converter provider
type Converter struct {
Autodetect []string `json:"autodetect" yaml:"autodetect"` // Optional, default is empty, if not set, will not use autodetect
MatchPriority int `json:"match_priority" yaml:"match_priority"` // Optional, default is 0, the higher the number, the higher the priority
}
// UTF8 is a converter provider for utf8 files
type UTF8 struct{ Converter }
// Office is a converter provider for office files, support docx, pptx.
type Office struct{ Converter }
// OCR is a converter provider for ocr files, support pdf, image.
type OCR struct{ Converter }
// Video is a converter provider for video files
type Video struct{ Converter }
// Whisper is a converter provider for audio files
type Whisper struct{ Converter }
// Vision is a converter provider for vision files
type Vision struct{ Converter }
// MCP is a converter provider for mcp files
type MCP struct{ Converter }
// AutoRegister registers the converter providers
func init() {
factory.Converters["__yao.utf8"] = &UTF8{
Converter: Converter{
Autodetect: []string{"text/plain", "text/markdown", ".txt", ".md"},
MatchPriority: 100,
},
}
factory.Converters["__yao.office"] = &Office{
Converter: Converter{
Autodetect: []string{"application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.presentationml.presentation", ".docx", ".pptx"},
MatchPriority: 10,
},
}
factory.Converters["__yao.ocr"] = &OCR{
Converter: Converter{
Autodetect: []string{"application/pdf", "image/jpeg", "image/png", "image/gif", "image/webp", ".pdf", ".jpg", ".jpeg", ".png", ".gif", ".webp"},
MatchPriority: 10,
},
}
factory.Converters["__yao.video"] = &Video{
Converter: Converter{
Autodetect: []string{"video/mp4", "video/mpeg", "video/quicktime", "video/webm", ".mp4", ".mpeg", ".mov", ".webm"},
MatchPriority: 10,
},
}
factory.Converters["__yao.whisper"] = &Whisper{
Converter: Converter{
Autodetect: []string{"audio/mpeg", "audio/wav", "audio/webm", ".mp3", ".wav", ".webm"},
MatchPriority: 10,
},
}
factory.Converters["__yao.vision"] = &Vision{
Converter: Converter{
Autodetect: []string{"image/jpeg", "image/png", "image/gif", "image/webp", ".jpg", ".jpeg", ".png", ".gif", ".webp"},
MatchPriority: 20,
},
}
factory.Converters["__yao.mcp"] = &MCP{Converter: Converter{}}
}
// AutoDetect detects the converter based on the filename and content types
func (c Converter) AutoDetect(filename, contentTypes string) (bool, int, error) {
// If autodetect is empty, return false
if c.Autodetect == nil {
return false, 0, nil
}
// Check if the filename matches the autodetect
for _, autodetect := range c.Autodetect {
if strings.HasSuffix(filename, autodetect) {
return true, c.MatchPriority, nil
}
// Check if the content types matches the autodetect
if strings.Contains(contentTypes, autodetect) {
return true, c.MatchPriority, nil
}
}
return false, 0, nil
}
// === UTF8 ===
// Make creates a new UTF8 converter
func (utf8 *UTF8) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
return converter.NewUTF8(), nil
}
// Schema returns the schema for the UTF8 converter
func (utf8 *UTF8) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Office ===
// Make creates a new Office converter
func (office *Office) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.OfficeOption
officeOption := converter.OfficeOption{
// VisionConverter: nil, // TODO: Get vision converter from option
// VideoConverter: nil, // TODO: Get video converter from option
// WhisperConverter: nil, // TODO: Get whisper converter from option
// MaxConcurrency: 0, // Will use default
// TempDir: "", // Will use default
// CleanupTemp: false,
}
return converter.NewOffice(officeOption)
}
// Schema returns the schema for the Office converter
func (office *Office) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === OCR ===
// Make creates a new OCR converter
func (ocr *OCR) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.OCROption
ocrOption := converter.OCROption{
// Vision: nil, // TODO: Get vision converter from option
// Mode: "", // Will use default
// MaxConcurrency: 0, // Will use default
// CompressSize: 0, // Will use default
// ForceImageMode: false,
}
return converter.NewOCR(ocrOption)
}
// Schema returns the schema for the OCR converter
func (ocr *OCR) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Video ===
// Make creates a new Video converter
func (video *Video) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.VideoOption
videoOption := converter.VideoOption{
// AudioConverter: nil, // TODO: Get audio converter from option
// VisionConverter: nil, // TODO: Get vision converter from option
// KeyframeInterval: 0, // Will use default
// MaxKeyframes: 0, // Will use default
// TempDir: "", // Will use default
// CleanupTemp: false,
// MaxConcurrency: 0, // Will use default
// TextOptimization: false,
// DeduplicationRatio: 0, // Will use default
}
return converter.NewVideo(videoOption)
}
// Schema returns the schema for the Video converter
func (video *Video) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Whisper ===
// Make creates a new Whisper converter
func (whisper *Whisper) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.WhisperOption
whisperOption := converter.WhisperOption{
// ConnectorName: "", // TODO: Get connector name from option
// Model: "", // Will use default
// Options: nil,
// Language: "", // Will use default
// ChunkDuration: 0, // Will use default
// MappingDuration: 0, // Will use default
// SilenceThreshold: 0, // Will use default
// SilenceMinLength: 0, // Will use default
// EnableSilenceDetection: false,
// MaxConcurrency: 0, // Will use default
// TempDir: "", // Will use default
// CleanupTemp: false,
}
return converter.NewWhisper(whisperOption)
}
// Schema returns the schema for the Whisper converter
func (whisper *Whisper) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Vision ===
// Make creates a new Vision converter
func (vision *Vision) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.VisionOption
visionOption := converter.VisionOption{
// ConnectorName: "", // TODO: Get connector name from option
// Model: "", // Will use default
// Prompt: "", // Will use default
// Options: nil,
// CompressSize: 0, // Will use default
// Language: "", // Will use default
}
return converter.NewVision(visionOption)
}
// Schema returns the schema for the Vision converter
func (vision *Vision) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === MCP ===
// Make creates a new MCP converter
func (mcp *MCP) Make(option *kbtypes.ProviderOption) (types.Converter, error) {
// TODO: Map kbtypes.ProviderOption to converter.MCPOptions
mcpOptions := &converter.MCPOptions{
// ID: "", // TODO: Get ID from option
// Tool: "", // TODO: Get tool from option
// ArgumentsMapping: nil, // TODO: Get arguments mapping from option
// ResultMapping: nil, // TODO: Get result mapping from option
// NotificationMapping: nil, // TODO: Get notification mapping from option
}
return converter.NewMCP(mcpOptions)
}
// Schema returns the schema for the MCP converter
func (mcp *MCP) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}

43
kb/providers/embedding.go Normal file
View file

@ -0,0 +1,43 @@
package providers
import (
"github.com/yaoapp/gou/graphrag/embedding"
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/yao/kb/providers/factory"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// OpenAI is an embedding provider
type OpenAI struct{}
// Fastembed is an embedding provider
type Fastembed struct{}
func init() {
factory.Embeddings["__yao.openai"] = &OpenAI{}
factory.Embeddings["__yao.fastembed"] = &Fastembed{}
}
// === OpenAI ===
// Make creates an OpenAI embedding provider
func (o *OpenAI) Make(option *kbtypes.ProviderOption) (types.Embedding, error) {
return embedding.NewOpenai(embedding.OpenaiOptions{})
}
// Schema returns the schema for the OpenAI embedding provider
func (o *OpenAI) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === Fastembed ===
// Make creates a Fastembed embedding provider
func (f *Fastembed) Make(option *kbtypes.ProviderOption) (types.Embedding, error) {
return embedding.NewFastEmbed(embedding.FastEmbedOptions{})
}
// Schema returns the schema for the Fastembed embedding provider
func (f *Fastembed) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}

41
kb/providers/extractor.go Normal file
View file

@ -0,0 +1,41 @@
package providers
import (
"github.com/yaoapp/gou/graphrag/extraction/openai"
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/yao/kb/providers/factory"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// ExtractorOpenAI is an extractor provider for entity and relationship extraction
type ExtractorOpenAI struct{}
// AutoRegister registers the extractor providers
func init() {
factory.Extractors["__yao.openai"] = &ExtractorOpenAI{}
}
// === ExtractorOpenAI ===
// Make creates a new OpenAI extractor
func (e *ExtractorOpenAI) Make(option *kbtypes.ProviderOption) (types.Extraction, error) {
// TODO: Map kbtypes.ProviderOption to openai.Options
openaiOptions := openai.Options{
// ConnectorName: "", // TODO: Get connector name from option
// Concurrent: 0, // Will use default
// Model: "", // Will use default
// Temperature: 0, // Will use default
// MaxTokens: 0, // Will use default
// Prompt: "", // Will use default
// Toolcall: nil, // Will use default
// Tools: nil, // Will use default
// RetryAttempts: 0, // Will use default
// RetryDelay: 0, // Will use default
}
return openai.NewOpenai(openaiOptions)
}
// Schema returns the schema for the OpenAI extractor
func (e *ExtractorOpenAI) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}

View file

@ -0,0 +1,151 @@
package factory
import (
"fmt"
"github.com/yaoapp/gou/graphrag/types"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// ProviderType is a type for provider types
type ProviderType string
const (
// ProviderTypeChunking is a type for chunking providers
ProviderTypeChunking ProviderType = "chunking"
// ProviderTypeConverter is a type for converter providers
ProviderTypeConverter ProviderType = "converter"
// ProviderTypeEmbedding is a type for embedding providers
ProviderTypeEmbedding ProviderType = "embedding"
// ProviderTypeExtractor is a type for extractor providers
ProviderTypeExtractor ProviderType = "extractor"
// ProviderTypeFetcher is a type for fetcher providers
ProviderTypeFetcher ProviderType = "fetcher"
)
// DetectMatch is a match for auto detect
type DetectMatch struct {
ID string
Priority int
}
// Chunkings is a map of chunking providers
var Chunkings = map[string]Chunking{}
// Converters is a map of converter providers
var Converters = map[string]Converter{}
// Embeddings is a map of embedding providers
var Embeddings = map[string]Embedding{}
// Extractors is a map of extractor providers
var Extractors = map[string]Extractor{}
// Fetchers is a map of fetcher providers
var Fetchers = map[string]Fetcher{}
// === Chunking API ===
// MakeChunking creates a new chunking provider
func MakeChunking(id string, option *kbtypes.ProviderOption) (types.Chunking, error) {
chunking, ok := Chunkings[id]
if !ok {
return nil, fmt.Errorf("chunking provider %s not found", id)
}
return chunking.Make(option)
}
// ChunkingOptions returns the options for a chunking provider
func ChunkingOptions(id string, option *kbtypes.ProviderOption) (*types.ChunkingOptions, error) {
chunking, ok := Chunkings[id]
if !ok {
return nil, fmt.Errorf("chunking provider %s not found", id)
}
return chunking.Options(option)
}
// === Converter API ===
// MakeConverter creates a new converter provider
func MakeConverter(id string, option *kbtypes.ProviderOption) (types.Converter, error) {
converter, ok := Converters[id]
if !ok {
return nil, fmt.Errorf("converter provider %s not found", id)
}
return converter.Make(option)
}
// AutoDetectConverter detects the converter based on the filename and content types
// return matched, id, error
func AutoDetectConverter(filename, contentTypes string) (bool, string, error) {
var highestPriority int = 0
var highestID string = ""
for id, converter := range Converters {
ok, priority, err := converter.AutoDetect(filename, contentTypes)
if err != nil {
continue
}
if ok && priority > highestPriority {
highestPriority = priority
highestID = id
}
}
return highestID != "", highestID, nil
}
// === Embedding API ===
// MakeEmbedding creates a new embedding provider
func MakeEmbedding(id string, option *kbtypes.ProviderOption) (types.Embedding, error) {
embedding, ok := Embeddings[id]
if !ok {
return nil, fmt.Errorf("embedding provider %s not found", id)
}
return embedding.Make(option)
}
// === Extractor API ===
// MakeExtractor creates a new extractor provider
func MakeExtractor(id string, option *kbtypes.ProviderOption) (types.Extraction, error) {
extractor, ok := Extractors[id]
if !ok {
return nil, fmt.Errorf("extractor provider %s not found", id)
}
return extractor.Make(option)
}
// === Fetcher API ===
// MakeFetcher creates a new fetcher provider
func MakeFetcher(id string, option *kbtypes.ProviderOption) (types.Fetcher, error) {
fetcher, ok := Fetchers[id]
if !ok {
return nil, fmt.Errorf("fetcher provider %s not found", id)
}
return fetcher.Make(option)
}
// === Schema API ===
// GetSchema returns the schema for a provider
func GetSchema(typ ProviderType, provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
var schema Schema = nil
var exists bool = false
switch typ {
case ProviderTypeChunking:
schema, exists = Chunkings[provider.ID]
case ProviderTypeConverter:
schema, exists = Converters[provider.ID]
case ProviderTypeEmbedding:
schema, exists = Embeddings[provider.ID]
case ProviderTypeExtractor:
schema, exists = Extractors[provider.ID]
case ProviderTypeFetcher:
schema, exists = Fetchers[provider.ID]
}
if !exists {
return nil, fmt.Errorf("%s provider %s not found", typ, provider.ID)
}
return schema.Schema(provider)
}

View file

@ -0,0 +1,43 @@
package factory
import (
"github.com/yaoapp/gou/graphrag/types"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// Chunking is a factory for chunking providers
type Chunking interface {
Make(option *kbtypes.ProviderOption) (types.Chunking, error)
Options(option *kbtypes.ProviderOption) (*types.ChunkingOptions, error)
Schema
}
// Converter is a factory for converter providers
type Converter interface {
Make(option *kbtypes.ProviderOption) (types.Converter, error)
AutoDetect(filename, contentTypes string) (bool, int, error)
Schema
}
// Embedding is a factory for embedding providers
type Embedding interface {
Make(options *kbtypes.ProviderOption) (types.Embedding, error)
Schema
}
// Extractor is a factory for extractor providers
type Extractor interface {
Make(option *kbtypes.ProviderOption) (types.Extraction, error)
Schema
}
// Fetcher is a factory for fetcher providers
type Fetcher interface {
Make(option *kbtypes.ProviderOption) (types.Fetcher, error)
Schema
}
// Schema interface for providers
type Schema interface {
Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error)
}

58
kb/providers/fetcher.go Normal file
View file

@ -0,0 +1,58 @@
package providers
import (
"github.com/yaoapp/gou/graphrag/fetcher"
"github.com/yaoapp/gou/graphrag/types"
"github.com/yaoapp/yao/kb/providers/factory"
kbtypes "github.com/yaoapp/yao/kb/types"
)
// FetcherHTTP is a fetcher provider for HTTP/HTTPS URLs
type FetcherHTTP struct{}
// FetcherMCP is a fetcher provider for MCP-based URL fetching
type FetcherMCP struct{}
// AutoRegister registers the fetcher providers
func init() {
factory.Fetchers["__yao.http"] = &FetcherHTTP{}
factory.Fetchers["__yao.mcp"] = &FetcherMCP{}
}
// === FetcherHTTP ===
// Make creates a new HTTP fetcher
func (f *FetcherHTTP) Make(option *kbtypes.ProviderOption) (types.Fetcher, error) {
// TODO: Map kbtypes.ProviderOption to fetcher.HTTPOptions
httpOptions := &fetcher.HTTPOptions{
// Headers: nil, // TODO: Get headers from option
// UserAgent: "", // Will use default
// Timeout: 0, // Will use default
}
return fetcher.NewHTTPFetcher(httpOptions), nil
}
// Schema returns the schema for the HTTP fetcher
func (f *FetcherHTTP) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}
// === FetcherMCP ===
// Make creates a new MCP fetcher
func (f *FetcherMCP) Make(option *kbtypes.ProviderOption) (types.Fetcher, error) {
// TODO: Map kbtypes.ProviderOption to fetcher.MCPOptions
mcpOptions := &fetcher.MCPOptions{
// ID: "", // TODO: Get ID from option
// Tool: "", // TODO: Get tool from option
// ArgumentsMapping: nil, // TODO: Get arguments mapping from option
// ResultMapping: nil, // TODO: Get result mapping from option
// NotificationMapping: nil, // TODO: Get notification mapping from option
}
return fetcher.NewMCP(mcpOptions)
}
// Schema returns the schema for the MCP fetcher
func (f *FetcherMCP) Schema(provider *kbtypes.Provider) (*kbtypes.ProviderSchema, error) {
return nil, nil
}

View file

@ -1,4 +1,4 @@
package kb
package types
import (
"encoding/json"

View file

@ -1,4 +1,4 @@
package kb
package types
import (
"encoding/json"

43
kb/types/provider.go Normal file
View file

@ -0,0 +1,43 @@
package types
import jsoniter "github.com/json-iterator/go"
// GetOption returns the option for a provider
func (p *Provider) GetOption(id string) (*ProviderOption, bool) {
if p.Options == nil {
return nil, false
}
// Find the option by id
for _, option := range p.Options {
if option.Value == id {
return option, true
}
}
return nil, false
}
// GetOptionByIndex returns the option by index
func (p *Provider) GetOptionByIndex(index int) (*ProviderOption, bool) {
if len(p.Options) <= index {
return nil, false
}
return p.Options[index], true
}
// Parse parses the provider option
func (p *ProviderOption) Parse(v interface{}) error {
raw, err := jsoniter.Marshal(p)
if err != nil {
return err
}
err = jsoniter.Unmarshal(raw, v)
if err != nil {
return err
}
return nil
}

View file

@ -1,4 +1,4 @@
package kb
package types
// Features represents the available features based on current configuration
type Features struct {