diff --git a/agent/search/DESIGN.md b/agent/search/DESIGN.md index 88f93681..4c06110a 100644 --- a/agent/search/DESIGN.md +++ b/agent/search/DESIGN.md @@ -447,7 +447,8 @@ type KeywordExtractor interface { // QueryDSLGenerator generates QueryDSL for DB search type QueryDSLGenerator interface { // Generate converts natural language to QueryDSL - Generate(ctx *context.Context, query string, schemas []*types.ModelSchema) (*types.QueryDSL, error) + // Uses GOU types directly: model.Model and gou.QueryDSL + Generate(query string, models []*model.Model) (*gou.QueryDSL, error) } // Note: Embedding is handled by KB collection's own config (embedding provider + model), @@ -480,6 +481,10 @@ All types are defined in `search/types/` package to prevent circular dependencie ```go package types +import ( + "github.com/yaoapp/gou/query/gou" +) + // SearchType represents the type of search type SearchType string @@ -516,28 +521,17 @@ type Request struct { Graph bool `json:"graph,omitempty"` // Enable graph association // Database search specific - Models []string `json:"models,omitempty"` // Model IDs (e.g., "user", "agents.mybot.product") - Wheres []QueryWhere `json:"wheres,omitempty"` // Pre-defined filters (optional) - Orders []QueryOrder `json:"orders,omitempty"` // Sort orders (optional) - Select []string `json:"select,omitempty"` // Fields to return (optional) + // Uses GOU QueryDSL types directly for compatibility with Yao's query system + // See: github.com/yaoapp/gou/query/gou/types.go + Models []string `json:"models,omitempty"` // Model IDs (e.g., "user", "agents.mybot.product") + Wheres []gou.Where `json:"wheres,omitempty"` // Pre-defined filters (optional), uses GOU QueryDSL Where + Orders gou.Orders `json:"orders,omitempty"` // Sort orders (optional), uses GOU QueryDSL Orders + Select []string `json:"select,omitempty"` // Fields to return (optional) // Reranking Rerank *RerankOptions `json:"rerank,omitempty"` } -// QueryWhere represents a filter condition for DB search -type QueryWhere struct { - Field string `json:"field"` // Field name - Op string `json:"op,omitempty"` // Operator: "=", "like", ">", "<", "in", etc. (default: "=") - Value interface{} `json:"value"` // Filter value -} - -// QueryOrder represents a sort order for DB search -type QueryOrder struct { - Field string `json:"field"` // Field name - Order string `json:"order,omitempty"` // "asc" or "desc" (default: "desc") -} - // RerankOptions controls result reranking // Reranker type is determined by uses.rerank in agent/agent.yml type RerankOptions struct { @@ -589,38 +583,20 @@ type ResultItem struct { // ProcessedQuery represents a processed query ready for execution type ProcessedQuery struct { - Type SearchType `json:"type"` - Keywords []string `json:"keywords,omitempty"` // For web search - Vector []float32 `json:"vector,omitempty"` // For KB search - DSL *QueryDSL `json:"dsl,omitempty"` // For DB search + Type SearchType `json:"type"` + Keywords []string `json:"keywords,omitempty"` // For web search + Vector []float32 `json:"vector,omitempty"` // For KB search + DSL *gou.QueryDSL `json:"dsl,omitempty"` // For DB search, uses GOU QueryDSL } -// QueryDSL represents a Yao QueryDSL for database search -type QueryDSL struct { - Model string `json:"model"` // Target model - Select []string `json:"select,omitempty"` // Fields to return - Wheres []QueryWhere `json:"wheres,omitempty"` // Filter conditions - Orders []QueryOrder `json:"orders,omitempty"` // Sort orders - Limit int `json:"limit,omitempty"` // Max results -} - -// ModelSchema represents a Yao Model schema for DSL generation -type ModelSchema struct { - ID string `json:"id"` // Model ID - Name string `json:"name"` // Model name - Description string `json:"description"` // Model description - Fields []FieldSchema `json:"fields"` // Field definitions -} - -// FieldSchema represents a field in the model schema -type FieldSchema struct { - Name string `json:"name"` // Field name - Type string `json:"type"` // Field type - Description string `json:"description"` // Field description - Searchable bool `json:"searchable"` // Whether field is searchable -} +// Note: For QueryDSL and Model types, use GOU types directly: +// - github.com/yaoapp/gou/query/gou.QueryDSL +// - github.com/yaoapp/gou/model.Model +// - github.com/yaoapp/gou/model.Column ``` +> **Note**: `Wheres` and `Orders` use GOU QueryDSL types directly (`gou.Where` and `gou.Orders`) for full compatibility with Yao's query system. See `github.com/yaoapp/gou/query/gou/types.go` for the complete type definitions. + ### Graph Types (`types/graph.go`) ```go @@ -920,22 +896,33 @@ interface KBOptions { interface DBOptions { models?: string[]; // Model IDs (default: use assistant's db.models) - wheres?: QueryWhere[]; // Pre-defined filters - orders?: QueryOrder[]; // Sort orders + wheres?: Where[]; // Pre-defined filters, uses GOU QueryDSL Where format + orders?: Order[]; // Sort orders, uses GOU QueryDSL Order format select?: string[]; // Fields to return limit?: number; // Max results (default: 10) rerank?: RerankOptions; } -interface QueryWhere { - field: string; - op?: string; // "=", "like", ">", "<", "in", etc. - value: any; +// GOU QueryDSL Where condition +// See: github.com/yaoapp/gou/query/gou/types.go +interface Where { + field: Expression; // Field expression + value?: any; // Match value + op: string; // Operator: "=", "like", ">", "<", ">=", "<=", "in", "is null", etc. + or?: boolean; // true for OR condition, default AND + wheres?: Where[]; // Nested conditions for grouping } -interface QueryOrder { - field: string; - order?: string; // "asc" or "desc" +// GOU QueryDSL Order +interface Order { + field: Expression; // Field expression + sort?: string; // "asc" or "desc" +} + +// GOU Expression (simplified) +interface Expression { + field?: string; // Field name + table?: string; // Table name (optional) } interface RerankOptions { @@ -1687,14 +1674,15 @@ func NewQueryDSLGenerator(usesQueryDSL string, cfg *types.QueryDSLConfig) *Query } // Generate converts natural language to QueryDSL -func (g *QueryDSLGenerator) Generate(ctx *context.Context, query string, schemas []*types.ModelSchema) (*types.QueryDSL, error) { +// Uses GOU types directly: model.Model and gou.QueryDSL +func (g *QueryDSLGenerator) Generate(query string, models []*model.Model) (*gou.QueryDSL, error) { switch { case g.usesQueryDSL == "builtin" || g.usesQueryDSL == "": - return g.builtinGenerate(query, schemas) + return g.builtinGenerate(query, models) case strings.HasPrefix(g.usesQueryDSL, "mcp:"): - return g.mcpGenerate(ctx, query, schemas) + return g.mcpGenerate(query, models) default: - return g.agentGenerate(ctx, query, schemas) + return g.agentGenerate(query, models) } } ``` diff --git a/agent/search/interfaces/nlp.go b/agent/search/interfaces/nlp.go index a387244e..b4a207a9 100644 --- a/agent/search/interfaces/nlp.go +++ b/agent/search/interfaces/nlp.go @@ -1,6 +1,8 @@ package interfaces import ( + "github.com/yaoapp/gou/model" + "github.com/yaoapp/gou/query/gou" "github.com/yaoapp/yao/agent/search/types" ) @@ -13,7 +15,7 @@ type KeywordExtractor interface { // QueryDSLGenerator generates QueryDSL for DB search type QueryDSLGenerator interface { // Generate converts natural language to QueryDSL - Generate(query string, schemas []*types.ModelSchema) (*types.QueryDSL, error) + Generate(query string, models []*model.Model) (*gou.QueryDSL, error) } // Note: Embedding is handled by KB collection's own config (embedding provider + model), diff --git a/agent/search/types/types.go b/agent/search/types/types.go index adad0157..6d089a64 100644 --- a/agent/search/types/types.go +++ b/agent/search/types/types.go @@ -1,8 +1,13 @@ package types +import ( + "github.com/yaoapp/gou/query/gou" +) + // SearchType represents the type of search type SearchType string +// SearchType constants const ( SearchTypeWeb SearchType = "web" // Web/Internet search SearchTypeKB SearchType = "kb" // Knowledge base vector search @@ -12,6 +17,7 @@ const ( // SourceType represents where the search result came from type SourceType string +// SourceType constants const ( SourceUser SourceType = "user" // User-provided DataContent (highest priority) SourceHook SourceType = "hook" // Hook ctx.search.*() results @@ -36,28 +42,15 @@ type Request struct { Graph bool `json:"graph,omitempty"` // Enable graph association // Database search specific - Models []string `json:"models,omitempty"` // Model IDs (e.g., "user", "agents.mybot.product") - Wheres []QueryWhere `json:"wheres,omitempty"` // Pre-defined filters (optional) - Orders []QueryOrder `json:"orders,omitempty"` // Sort orders (optional) - Select []string `json:"select,omitempty"` // Fields to return (optional) + Models []string `json:"models,omitempty"` // Model IDs (e.g., "user", "agents.mybot.product") + Wheres []gou.Where `json:"wheres,omitempty"` // Pre-defined filters (optional), uses GOU QueryDSL Where + Orders gou.Orders `json:"orders,omitempty"` // Sort orders (optional), uses GOU QueryDSL Orders + Select []string `json:"select,omitempty"` // Fields to return (optional) // Reranking Rerank *RerankOptions `json:"rerank,omitempty"` } -// QueryWhere represents a filter condition for DB search -type QueryWhere struct { - Field string `json:"field"` // Field name - Op string `json:"op,omitempty"` // Operator: "=", "like", ">", "<", "in", etc. (default: "=") - Value interface{} `json:"value"` // Filter value -} - -// QueryOrder represents a sort order for DB search -type QueryOrder struct { - Field string `json:"field"` // Field name - Order string `json:"order,omitempty"` // "asc" or "desc" (default: "desc") -} - // RerankOptions controls result reranking // Reranker type is determined by uses.rerank in agent/agent.yml type RerankOptions struct { @@ -109,33 +102,13 @@ type ResultItem struct { // ProcessedQuery represents a processed query ready for execution type ProcessedQuery struct { - Type SearchType `json:"type"` - Keywords []string `json:"keywords,omitempty"` // For web search - Vector []float32 `json:"vector,omitempty"` // For KB search - DSL *QueryDSL `json:"dsl,omitempty"` // For DB search + Type SearchType `json:"type"` + Keywords []string `json:"keywords,omitempty"` // For web search + Vector []float32 `json:"vector,omitempty"` // For KB search + DSL *gou.QueryDSL `json:"dsl,omitempty"` // For DB search, uses GOU QueryDSL } -// QueryDSL represents a Yao QueryDSL for database search -type QueryDSL struct { - Model string `json:"model"` // Target model - Select []string `json:"select,omitempty"` // Fields to return - Wheres []QueryWhere `json:"wheres,omitempty"` // Filter conditions - Orders []QueryOrder `json:"orders,omitempty"` // Sort orders - Limit int `json:"limit,omitempty"` // Max results -} - -// ModelSchema represents a Yao Model schema for DSL generation -type ModelSchema struct { - ID string `json:"id"` // Model ID - Name string `json:"name"` // Model name - Description string `json:"description"` // Model description - Fields []FieldSchema `json:"fields"` // Field definitions -} - -// FieldSchema represents a field in the model schema -type FieldSchema struct { - Name string `json:"name"` // Field name - Type string `json:"type"` // Field type - Description string `json:"description"` // Field description - Searchable bool `json:"searchable"` // Whether field is searchable -} +// Note: For QueryDSL and Model types, use GOU types directly: +// - github.com/yaoapp/gou/query/gou.QueryDSL +// - github.com/yaoapp/gou/model.Model +// - github.com/yaoapp/gou/model.Column