1010from osw .service .registry import operation
1111from osw .service .serialization import cap_list , to_jsonable
1212from osw .sparql_client_smw import SmwSparqlClient
13+ from osw .wiki_tools import get_query_limit
1314from osw .wtsite import WtSite
1415
1516
17+ def _hit_limit (total : int , limit : Optional [int ]) -> bool :
18+ """Whether a result set is as large as the limit that produced it.
19+
20+ The wiki applies the limit itself, so ``cap_list`` never has to cut these
21+ results and its own flag stays False. A full result set is then the only
22+ signal left that the wiki may hold further matches. ``limit=0`` asks for
23+ no results, so meeting it says nothing about truncation.
24+ """
25+ return bool (limit ) and total >= limit
26+
27+
1628@operation (
1729 group = "search" ,
1830 cli_name = "ask" ,
@@ -42,16 +54,28 @@ def search_entities(ctx: Context, ask_query: str, limit: Optional[int] = None) -
4254 ``@context`` of its schema, so read it with ``osw schema get`` when a
4355 name query returns nothing.
4456
45- ``limit`` defaults to ``OSW_MAX_RESULTS`` (100 when that is unset).
57+ ``limit`` defaults to ``OSW_MAX_RESULTS`` (100 when that is unset). A
58+ ``limit=N`` written into the query itself wins over it.
4659 Returns ``{titles, count, truncated}``, where ``titles`` are full page
47- names and ``count`` is how many the wiki returned.
60+ names, ``count`` is how many the wiki returned and ``truncated`` reports
61+ that further matches may exist beyond them.
4862 """
4963 lim = ctx .limit (limit )
5064 titles = ctx .osw .site .semantic_search (
5165 WtSite .SearchParam (query = ask_query , limit = lim )
5266 )
67+ # semantic_search lets a 'limit=' written into the query win over `lim`,
68+ # so the flag has to compare against the limit that reached the wiki.
69+ # `titles` excludes hits whose page does not exist, so a result set
70+ # thinned that way reads as not truncated.
71+ query_limit = get_query_limit (ask_query )
72+ effective_limit = lim if query_limit is None else query_limit
5373 capped , total , truncated = cap_list (titles , lim )
54- return {"titles" : capped , "count" : total , "truncated" : truncated }
74+ return {
75+ "titles" : capped ,
76+ "count" : total ,
77+ "truncated" : truncated or _hit_limit (total , effective_limit ),
78+ }
5579
5680
5781@operation (
@@ -74,12 +98,17 @@ def search_titles(ctx: Context, text: str, limit: Optional[int] = None) -> dict:
7498
7599 ``limit`` defaults to ``OSW_MAX_RESULTS`` (100 when that is unset).
76100 Returns ``{titles, count, truncated}``, where ``titles`` are full page
77- names and ``count`` is how many the wiki returned.
101+ names, ``count`` is how many the wiki returned and ``truncated`` reports
102+ that further matches may exist beyond them.
78103 """
79104 lim = ctx .limit (limit )
80105 titles = ctx .osw .site .prefix_search (WtSite .SearchParam (query = text , limit = lim ))
81106 capped , total , truncated = cap_list (titles , lim )
82- return {"titles" : capped , "count" : total , "truncated" : truncated }
107+ return {
108+ "titles" : capped ,
109+ "count" : total ,
110+ "truncated" : truncated or _hit_limit (total , lim ),
111+ }
83112
84113
85114@operation (
@@ -98,13 +127,18 @@ def search_content(ctx: Context, text: str, limit: Optional[int] = None) -> dict
98127
99128 Returns page titles, not the matching passages. ``limit`` defaults to
100129 ``OSW_MAX_RESULTS`` (100 when that is unset). Returns
101- ``{titles, count, truncated}``, where ``titles`` are full page names
102- and ``count`` is how many the wiki returned.
130+ ``{titles, count, truncated}``, where ``titles`` are full page names,
131+ ``count`` is how many the wiki returned and ``truncated`` reports that
132+ further matches may exist beyond them.
103133 """
104134 lim = ctx .limit (limit )
105135 titles = ctx .osw .site .content_search (WtSite .SearchParam (query = text , limit = lim ))
106136 capped , total , truncated = cap_list (titles , lim )
107- return {"titles" : capped , "count" : total , "truncated" : truncated }
137+ return {
138+ "titles" : capped ,
139+ "count" : total ,
140+ "truncated" : truncated or _hit_limit (total , lim ),
141+ }
108142
109143
110144@operation (
@@ -125,14 +159,19 @@ def list_instances_of_category(
125159
126160 ``limit`` defaults to ``OSW_MAX_RESULTS`` (100 when that is unset).
127161 Returns ``{titles, count, truncated}``, where ``titles`` are full page
128- names and ``count`` is how many the wiki returned.
162+ names, ``count`` is how many the wiki returned and ``truncated`` reports
163+ that further matches may exist beyond them.
129164 """
130165 lim = ctx .limit (limit )
131166 titles = ctx .osw .query_instances (
132167 OSW .QueryInstancesParam (categories = category , limit = lim )
133168 )
134169 capped , total , truncated = cap_list (titles , lim )
135- return {"titles" : capped , "count" : total , "truncated" : truncated }
170+ return {
171+ "titles" : capped ,
172+ "count" : total ,
173+ "truncated" : truncated or _hit_limit (total , lim ),
174+ }
136175
137176
138177@operation (
0 commit comments