feat: Add empty query support to llm_search for listing all artifacts

Changes:
- fts_search_llm(): Empty query now returns all artifacts (list mode)
- Update llm.search tool: query parameter is now optional
- Tool description mentions empty query lists all artifacts
- Add body field to llm_search results
- Update demo script: Add special case for "What questions can I ask?"

This enables agents to retrieve all pre-defined question templates
when users ask what questions are available, instead of inferring
questions from schema.
pull/5318/head
Rene Cannao 3 months ago
parent be675d4165
commit 1b42cfbd27

@ -1917,8 +1917,14 @@ std::string Discovery_Schema::fts_search_llm(
SQLite3_result* resultset = NULL;
std::ostringstream sql;
sql << "SELECT kind, key, title , bm25(fts_llm) AS score FROM fts_llm "
<< "WHERE fts_llm MATCH '" << query << "' ORDER BY score LIMIT " << limit << ";";
// Empty query returns all results (list mode), otherwise search
if (query.empty()) {
sql << "SELECT kind, key, title, body , 0.0 AS score FROM fts_llm "
<< "ORDER BY kind, title LIMIT " << limit << ";";
} else {
sql << "SELECT kind, key, title, body , bm25(fts_llm) AS score FROM fts_llm "
<< "WHERE fts_llm MATCH '" << query << "' ORDER BY score LIMIT " << limit << ";";
}
db->execute_statement(sql.str().c_str(), &error, &cols, &affected, &resultset);
@ -1932,7 +1938,8 @@ std::string Discovery_Schema::fts_search_llm(
item["kind"] = std::string(row->fields[0] ? row->fields[0] : "");
item["key"] = std::string(row->fields[1] ? row->fields[1] : "");
item["title"] = std::string(row->fields[2] ? row->fields[2] : "");
item["score"] = atof(row->fields[3] ? row->fields[3] : "0");
item["body"] = std::string(row->fields[3] ? row->fields[3] : "");
item["score"] = atof(row->fields[4] ? row->fields[4] : "0");
results.push_back(item);
}

@ -643,9 +643,9 @@ json Query_Tool_Handler::get_tool_list() {
tools.push_back(create_tool_schema(
"llm.search",
"Full-text search across LLM artifacts (summaries/domains/metrics/templates/notes) using fts_llm.",
{"run_id", "query"},
{{"limit", "integer"}}
"Full-text search across LLM artifacts (summaries/domains/metrics/templates/notes) using fts_llm. Use empty query string to list all artifacts.",
{"run_id"},
{{"query", "string"}, {"limit", "integer"}}
));
// ============================================================
@ -1408,8 +1408,6 @@ json Query_Tool_Handler::execute_tool(const std::string& tool_name, const json&
if (run_id_or_schema.empty()) {
result = create_error_response("run_id is required");
} else if (query.empty()) {
result = create_error_response("query is required");
} else {
// Resolve schema name to run_id if needed
int run_id = catalog->resolve_run_id(run_id_or_schema);

@ -88,6 +88,38 @@ Here are the results:
- **If no good match**: Generate SQL from scratch using catalog schema
- **run_id**: Always use '${SCHEMA}' as the run_id
## Special Case: "What questions can I ask?"
When the user asks:
- "What questions can I ask?"
- "What are some example questions?"
- "Show me available questions"
**DO NOT** infer questions from schema. Instead:
1. Call `llm_search` with `query=""` (empty string) to list all existing question templates
2. Present the question templates grouped by type (question_template, metric, etc.)
3. Show the title and body (the actual question) for each
Example:
```
User: "What questions can I ask?"
Step 1: List all available question templates...
[Call llm_search with query=""]
Step 2: Found X pre-defined questions:
📊 Question Templates:
- "What is the total revenue?"
- "Who are the top customers?"
...
📈 Metrics:
- "Revenue by Country"
- "Monthly Revenue Trend"
...
```
## Example Interaction
User: \"What are the most expensive tracks?\"

Loading…
Cancel
Save