Rank a search the same whatever order discovery heard things in
A tie went to whichever tool discovery listed first, so docker logs found docker_secrets_in_logs before docker_logs on some runs. A name the query says whole wins, then the shorter name.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package console
|
||||
|
||||
// Finding a tool by the words an agent already has (novox/hq ADR 0242).
|
||||
// Finding a tool by the words an agent already has (novox/hq ADR 0245).
|
||||
//
|
||||
// An agent that wants a unit's log reaches for `journalctl`, and one that wants a container's for `docker
|
||||
// logs`; it searches with those words, or with `logs`. Matched against names and descriptions alone, none
|
||||
@@ -12,10 +12,11 @@ package console
|
||||
// every word of the replaced command, in order, among the query's words. The most specific command wins.
|
||||
// 2. **Every word is in the tool's name, its replaced commands or its description**, a word also matching
|
||||
// through a short table of the words agents use for the mesh's (logs ⇄ journal, ps ⇄ list). A word in
|
||||
// the name or a replaced command weighs more than one in the description.
|
||||
// the name or a replaced command weighs more than one in the description, and a name the query says
|
||||
// whole more than one it says in part.
|
||||
// 3. Nothing else: a search that matches nothing says so.
|
||||
//
|
||||
// Ties keep the listing's order — seats first, the place tools belong — then the modules by name.
|
||||
// Ties go to a seat — the place tools belong — then to the shorter name, then by address.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -149,6 +150,19 @@ func scoreOf(query string, qwords []string, name, description string, replaces [
|
||||
score += found
|
||||
}
|
||||
}
|
||||
// A name the query says whole — `docker logs` for docker_logs, not docker_secrets_in_logs — first.
|
||||
own := name[strings.LastIndex(name, ".")+1:]
|
||||
whole := true
|
||||
for _, part := range strings.FieldsFunc(strings.ToLower(own), func(r rune) bool { return r == '_' || r == '-' }) {
|
||||
in := false
|
||||
for _, w := range qwords {
|
||||
in = in || w == part
|
||||
}
|
||||
whole = whole && in
|
||||
}
|
||||
if whole {
|
||||
score += 2
|
||||
}
|
||||
return score, ""
|
||||
}
|
||||
|
||||
@@ -208,11 +222,22 @@ func (x *index) search(query string) []hit {
|
||||
hits = append(hits, h)
|
||||
}
|
||||
}
|
||||
sort.SliceStable(hits, func(i, j int) bool { return hits[i].score > hits[j].score })
|
||||
// Best first; on a tie the shorter name — the plainer tool — then the address, so an answer never
|
||||
// depends on the order discovery heard things in.
|
||||
sort.SliceStable(hits, func(i, j int) bool {
|
||||
if hits[i].score != hits[j].score {
|
||||
return hits[i].score > hits[j].score
|
||||
}
|
||||
a, b := hits[i].Address[strings.LastIndex(hits[i].Address, ".")+1:], hits[j].Address[strings.LastIndex(hits[j].Address, ".")+1:]
|
||||
if len(a) != len(b) {
|
||||
return len(a) < len(b)
|
||||
}
|
||||
return hits[i].Address < hits[j].Address
|
||||
})
|
||||
return hits
|
||||
}
|
||||
|
||||
// replacesOf is what every verb and tool replaces, from the controller's records (novox/hq ADR 0242):
|
||||
// replacesOf is what every verb and tool replaces, from the controller's records (novox/hq ADR 0245):
|
||||
// a seat's verbs from its `tools` answer, keyed `seat:<seat>.<verb>`, and a module's own tools from
|
||||
// its `modules` answer, keyed `<module>.<tool>`. A controller older than the field answers neither,
|
||||
// and search matches names and descriptions as before.
|
||||
|
||||
Reference in New Issue
Block a user