Skip to content

Commit 264edc8

Browse files
committed
feat: enhance robot alias management and search functionality
- Added methods to the RobotAliasManager for resolving robot IDs to canonical keys and searching by aliases. - Updated FilterManager to include fallback search by robot aliases, improving dataset search capabilities. - Added PROMPTS.md to .gitignore to prevent tracking of prompt files.
1 parent c90fc7b commit 264edc8

3 files changed

Lines changed: 69 additions & 4 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/assets
1+
/assets
2+
PROMPTS.md

docs/js/modules/@filter/filter-manager.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,24 @@ export class FilterManager {
333333
// Keyword search: match against dataset id/name and robot aliases / friendly names
334334
if (normalizedQuery) {
335335
const texts = this.getSearchableTextsForDataset(ds);
336-
const matchesSearch = texts.some(text =>
336+
let matchesSearch = texts.some(text =>
337337
typeof text === 'string' && text.toLowerCase().includes(normalizedQuery)
338338
);
339-
339+
// Fallback: match by alias reverse lookup (e.g. "宇树" -> robot keys that have this alias)
340+
if (!matchesSearch && this.robotAliasManager && typeof this.robotAliasManager.getRobotIdsByAlias === 'function') {
341+
const robotIdsByAlias = this.robotAliasManager.getRobotIdsByAlias(normalizedQuery);
342+
if (robotIdsByAlias.length > 0) {
343+
const dsRobots = Array.isArray(ds.robot) ? ds.robot : (ds.robot != null ? [ds.robot] : []);
344+
const aliasKeysLower = new Set(robotIdsByAlias.map(id => String(id).toLowerCase()));
345+
const getCanonical = typeof this.robotAliasManager.getCanonicalRobotKey === 'function'
346+
? (r) => this.robotAliasManager.getCanonicalRobotKey(r)
347+
: (r) => (r != null ? String(r) : null);
348+
matchesSearch = dsRobots.some(r => {
349+
const canonical = getCanonical(r);
350+
return canonical != null && aliasKeysLower.has(canonical.toLowerCase());
351+
});
352+
}
353+
}
340354
if (!matchesSearch) {
341355
return false;
342356
}

docs/js/modules/robot-aliases.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,18 @@ class RobotAliasManager {
6868

6969
/**
7070
* Get raw alias entry for a robot ID.
71+
* Tries exact key first, then case-insensitive match so that dataset robot_type
72+
* (e.g. "G1EDU-U3") still resolves to the same entry as alias key "G1edu-u3".
7173
* @param {string} robotId
7274
* @returns {{ common_name?: string, aliases?: string[] } | null}
7375
*/
7476
getAliasEntry(robotId) {
7577
if (!robotId) return null;
76-
return this.aliasMap[robotId] || null;
78+
const idStr = String(robotId);
79+
if (this.aliasMap[idStr]) return this.aliasMap[idStr];
80+
const idLower = idStr.toLowerCase();
81+
const key = Object.keys(this.aliasMap).find(k => k.toLowerCase() === idLower);
82+
return key ? this.aliasMap[key] : null;
7783
}
7884

7985
/**
@@ -127,6 +133,50 @@ class RobotAliasManager {
127133
getAliasKeys() {
128134
return Object.keys(this.aliasMap);
129135
}
136+
137+
/**
138+
* Resolve a robot id (may be alias or key) to the canonical key in alias map.
139+
* Tries exact key, case-insensitive key, then any key whose common_name or aliases contain this id.
140+
* @param {string} robotId
141+
* @returns {string|null} Canonical key or null
142+
*/
143+
getCanonicalRobotKey(robotId) {
144+
if (!robotId) return null;
145+
const idStr = String(robotId).trim();
146+
if (this.aliasMap[idStr]) return idStr;
147+
const idLower = idStr.toLowerCase();
148+
const byKey = Object.keys(this.aliasMap).find(k => k.toLowerCase() === idLower);
149+
if (byKey) return byKey;
150+
for (const [key, entry] of Object.entries(this.aliasMap)) {
151+
if (entry.common_name && String(entry.common_name).toLowerCase() === idLower) return key;
152+
if (Array.isArray(entry.aliases) && entry.aliases.some(a => a && String(a).toLowerCase() === idLower)) return key;
153+
}
154+
return null;
155+
}
156+
157+
/**
158+
* Find robot map keys whose tokens (id, common_name, aliases) contain the query.
159+
* Used for search: when user types e.g. "宇树", returns ["G1edu-u3"] so that
160+
* datasets with robot "G1edu-u3" (or case variant) match even if getSearchTokensForRobot
161+
* was not used (e.g. robot_type key mismatch or missing in data).
162+
* @param {string} query - Search substring (will be compared case-insensitively for ASCII)
163+
* @returns {string[]} Canonical robot keys from alias map that have query in their tokens
164+
*/
165+
getRobotIdsByAlias(query) {
166+
if (!query || typeof query !== 'string') return [];
167+
const q = query.trim();
168+
if (!q) return [];
169+
const qLower = q.toLowerCase();
170+
const result = [];
171+
Object.keys(this.aliasMap).forEach(robotKey => {
172+
const tokens = this.getSearchTokensForRobot(robotKey);
173+
const hasMatch = tokens.some(t =>
174+
typeof t === 'string' && t.toLowerCase().includes(qLower)
175+
);
176+
if (hasMatch) result.push(robotKey);
177+
});
178+
return result;
179+
}
130180
}
131181

132182
// Export singleton instance

0 commit comments

Comments
 (0)