| 137 | } |
| 138 | |
| 139 | func (t *searchTool) Execute(ctx context.Context, input map[string]any, _ *tools.ToolContext) (any, error) { |
| 140 | query, _ := input["query"].(string) |
| 141 | if query == "" { |
| 142 | return map[string]any{"ok": false, "error": "query is required"}, nil |
| 143 | } |
| 144 | topK := 5 |
| 145 | if v, ok := input["top_k"].(int); ok && v > 0 { |
| 146 | topK = v |
| 147 | } |
| 148 | ns, _ := input["namespace"].(string) |
| 149 | meta := map[string]any{} |
| 150 | if m, ok := input["metadata"].(map[string]any); ok { |
| 151 | maps.Copy(meta, m) |
| 152 | } |
| 153 | if ns != "" { |
| 154 | meta["namespace"] = ns |
| 155 | } |
| 156 | |
| 157 | hits, err := t.pipe.Search(ctx, query, topK, meta) |
| 158 | if err != nil { |
| 159 | return map[string]any{"ok": false, "error": err.Error()}, nil |
| 160 | } |
| 161 | |
| 162 | results := make([]map[string]any, 0, len(hits)) |
| 163 | for _, h := range hits { |
| 164 | results = append(results, map[string]any{ |
| 165 | "id": h.ID, |
| 166 | "score": h.Score, |
| 167 | "text": h.Text, |
| 168 | "metadata": h.Metadata, |
| 169 | }) |
| 170 | } |
| 171 | |
| 172 | return map[string]any{ |
| 173 | "ok": true, |
| 174 | "query": query, |
| 175 | "namespace": ns, |
| 176 | "results": results, |
| 177 | }, nil |
| 178 | } |