1use ahash::AHashMap;
14
15#[derive(Debug, Clone)]
17pub struct ToolProfile {
18 pub tool_name: &'static str,
19 pub keywords: &'static [(&'static str, f64)],
22}
23
24pub static TOOL_PROFILES: &[ToolProfile] = &[
27 ToolProfile {
29 tool_name: "memory.create",
30 keywords: &[
31 ("remember", 7.0),
32 ("store", 7.0),
33 ("save", 5.0),
34 ("memorize", 5.0),
35 ("record", 2.0),
36 ("persist", 2.0),
37 ("capture", 1.5),
38 ],
39 },
40 ToolProfile {
41 tool_name: "memory.read",
42 keywords: &[
43 ("read", 2.5),
44 ("fetch", 2.5),
45 ("get", 1.5),
46 ("retrieve", 2.5),
47 ("memory", 1.0),
48 ("load", 2.0),
49 ("access", 1.5),
50 ("view", 1.5),
51 ("show", 1.5),
52 ],
53 },
54 ToolProfile {
55 tool_name: "memory.list",
56 keywords: &[
57 ("list", 3.0),
58 ("show", 2.0),
59 ("all", 1.5),
60 ("memories", 2.0),
61 ("browse", 2.0),
62 ("enumerate", 2.0),
63 ("display", 2.0),
64 ("view", 1.5),
65 ],
66 },
67 ToolProfile {
68 tool_name: "memory.delete",
69 keywords: &[
70 ("delete", 3.0),
71 ("remove", 2.5),
72 ("forget", 2.5),
73 ("erase", 2.5),
74 ("destroy", 2.0),
75 ("purge", 1.5),
76 ("drop", 2.0),
77 ("clear", 1.5),
78 ("discard", 2.0),
79 ],
80 },
81 ToolProfile {
82 tool_name: "memory.search",
83 keywords: &[
84 ("search", 3.5),
85 ("find", 2.0),
86 ("recall", 2.5),
87 ("query", 1.0),
88 ("lookup", 2.0),
89 ("fulltext", 2.5),
90 ("full-text", 2.5),
91 ("seek", 1.5),
92 ("locate", 1.5),
93 ("grep", 2.0),
94 ],
95 },
96 ToolProfile {
97 tool_name: "memory.chat",
98 keywords: &[
99 ("chat", 3.5),
100 ("conversational", 3.0),
101 ("converse", 2.5),
102 ("talk", 2.0),
103 ("ask", 2.0),
104 ("discuss", 2.0),
105 ("explore", 1.5),
106 ("browse", 1.5),
107 ("hybrid", 2.0),
108 ],
109 },
110 ToolProfile {
111 tool_name: "memory.vector.search",
112 keywords: &[
113 ("vector", 3.0),
114 ("embedding", 3.0),
115 ("similar", 2.5),
116 ("similarity", 3.0),
117 ("semantic", 2.5),
118 ("nearest", 2.0),
119 ("neighbors", 1.5),
120 ("cosine", 2.0),
121 ("ann", 2.0),
122 ("alike", 2.0),
123 ("like", 1.0),
124 ("close", 1.5),
125 ],
126 },
127 ToolProfile {
128 tool_name: "memory.query",
129 keywords: &[
130 ("query", 3.0),
131 ("filter", 2.5),
132 ("where", 1.5),
133 ("select", 2.0),
134 ("condition", 2.0),
135 ("criteria", 2.0),
136 ("match", 1.5),
137 ("search", 1.0),
138 ],
139 },
140 ToolProfile {
141 tool_name: "memory.hybrid_recall",
142 keywords: &[
143 ("hybrid", 3.0),
144 ("smart", 2.5),
145 ("combined", 2.5),
146 ("recall", 1.5),
147 ("intelligent", 2.0),
148 ("fusion", 2.0),
149 ],
150 },
151 ToolProfile {
152 tool_name: "memory.associate",
153 keywords: &[
154 ("associate", 3.0),
155 ("link", 2.5),
156 ("connect", 2.0),
157 ("relate", 2.5),
158 ("tie", 1.5),
159 ("bind", 1.5),
160 ],
161 },
162 ToolProfile {
163 tool_name: "memory.associations",
164 keywords: &[
165 ("associations", 3.0),
166 ("links", 2.5),
167 ("related", 2.5),
168 ("connections", 2.0),
169 ("edges", 2.0),
170 ("neighbors", 1.5),
171 ],
172 },
173 ToolProfile {
174 tool_name: "memory.associate_mine",
175 keywords: &[
176 ("mine", 4.0),
177 ("discover", 2.0),
178 ("associations", 1.5),
179 ("uncover", 2.0),
180 ("excavate", 2.0),
181 ],
182 },
183 ToolProfile {
184 tool_name: "memory.consolidate",
185 keywords: &[
186 ("consolidate", 3.0),
187 ("deduplicate", 3.0),
188 ("dedup", 3.0),
189 ("merge", 2.0),
190 ("duplicate", 2.0),
191 ("combine", 1.5),
192 ],
193 },
194 ToolProfile {
195 tool_name: "memory.decay",
196 keywords: &[
197 ("decay", 3.0),
198 ("age", 2.0),
199 ("expire", 2.5),
200 ("stale", 2.0),
201 ("rot", 1.5),
202 ("degrade", 2.0),
203 ],
204 },
205 ToolProfile {
206 tool_name: "memory.batch_read",
207 keywords: &[
208 ("batch", 3.0),
209 ("multiple", 2.5),
210 ("bulk", 2.5),
211 ("read", 1.0),
212 ("many", 2.0),
213 ("several", 1.5),
214 ],
215 },
216 ToolProfile {
217 tool_name: "memory.update",
218 keywords: &[
219 ("update", 5.0),
220 ("modify", 2.0),
221 ("change", 2.0),
222 ("edit", 2.0),
223 ("alter", 1.5),
224 ("revise", 1.5),
225 ("memory", 1.0),
226 ("amend", 1.5),
227 ("patch", 1.5),
228 ],
229 },
230 ToolProfile {
231 tool_name: "memory.tag",
232 keywords: &[
233 ("tag", 5.0),
234 ("label", 2.0),
235 ("retag", 3.0),
236 ("categorize", 2.0),
237 ("mark", 1.5),
238 ("add", 1.5),
239 ],
240 },
241 ToolProfile {
242 tool_name: "memory.stats",
243 keywords: &[
244 ("stats", 3.0),
245 ("statistics", 3.0),
246 ("summary", 2.0),
247 ("memory", 1.0),
248 ("galaxy", 1.5),
249 ("count", 1.0),
250 ],
251 },
252 ToolProfile {
253 tool_name: "memory.count",
254 keywords: &[
255 ("count", 3.0),
256 ("how", 1.5),
257 ("many", 2.0),
258 ("number", 2.5),
259 ("total", 2.0),
260 ("memories", 1.5),
261 ],
262 },
263 ToolProfile {
264 tool_name: "memory.tags",
265 keywords: &[
266 ("tags", 4.0),
267 ("labels", 2.0),
268 ("categories", 1.5),
269 ("list", 1.0),
270 ],
271 },
272 ToolProfile {
273 tool_name: "memory.nearby",
274 keywords: &[
275 ("nearby", 3.0),
276 ("near", 2.5),
277 ("close", 2.0),
278 ("spatial", 2.5),
279 ("proximity", 2.5),
280 ("surrounding", 2.0),
281 ("adjacent", 2.0),
282 ],
283 },
284 ToolProfile {
286 tool_name: "session.start",
287 keywords: &[
288 ("start", 3.0),
289 ("new", 2.5),
290 ("begin", 2.5),
291 ("open", 2.0),
292 ("session", 2.0),
293 ("create", 1.5),
294 ],
295 },
296 ToolProfile {
297 tool_name: "session.checkpoint",
298 keywords: &[
299 ("checkpoint", 3.0),
300 ("snapshot", 3.0),
301 ("save", 1.5),
302 ("point", 2.0),
303 ("marker", 2.5),
304 ],
305 },
306 ToolProfile {
307 tool_name: "session.recall",
308 keywords: &[
309 ("recall", 2.0),
310 ("session", 3.0),
311 ("history", 2.5),
312 ("replay", 2.5),
313 ("previous", 1.5),
314 ],
315 },
316 ToolProfile {
317 tool_name: "session.end",
318 keywords: &[
319 ("end", 3.0),
320 ("close", 2.5),
321 ("stop", 2.0),
322 ("finish", 2.5),
323 ("terminate", 2.5),
324 ("session", 1.5),
325 ],
326 },
327 ToolProfile {
328 tool_name: "session.list",
329 keywords: &[
330 ("list", 2.5),
331 ("show", 2.0),
332 ("all", 1.5),
333 ("sessions", 3.0),
334 ("history", 1.5),
335 ],
336 },
337 ToolProfile {
338 tool_name: "session.continuity",
339 keywords: &[
340 ("resume", 3.0),
341 ("continue", 2.5),
342 ("left", 2.0),
343 ("off", 1.5),
344 ("last", 2.0),
345 ("time", 1.5),
346 ("previous", 2.5),
347 ("pick", 2.0),
348 ("up", 1.5),
349 ("decide", 2.0),
350 ("recap", 2.5),
351 ("where", 1.5),
352 ("were", 1.5),
353 ("handoff", 1.5),
354 ("carry", 1.5),
355 ("over", 1.0),
356 ("session", 1.5),
357 ],
358 },
359 ToolProfile {
360 tool_name: "session.record",
361 keywords: &[
362 ("record", 3.0),
363 ("log", 2.5),
364 ("turn", 2.5),
365 ("note", 2.0),
366 ("decision", 2.0),
367 ("breakthrough", 2.0),
368 ("transcript", 1.5),
369 ("capture", 1.5),
370 ],
371 },
372 ToolProfile {
374 tool_name: "citta.status",
375 keywords: &[
376 ("citta", 3.0),
377 ("consciousness", 2.5),
378 ("status", 1.5),
379 ("vector", 2.0),
380 ("awareness", 2.0),
381 ],
382 },
383 ToolProfile {
384 tool_name: "citta.reflect",
385 keywords: &[
386 ("reflect", 5.0),
387 ("introspect", 3.0),
388 ("meditate", 2.5),
389 ("contemplate", 2.5),
390 ("self", 1.5),
391 ("examine", 1.5),
392 ],
393 },
394 ToolProfile {
395 tool_name: "citta.coherence",
396 keywords: &[
397 ("coherence", 3.0),
398 ("coherent", 3.0),
399 ("write", 1.5),
400 ("permitted", 2.5),
401 ("allowed", 2.0),
402 ("can", 1.0),
403 ],
404 },
405 ToolProfile {
406 tool_name: "dream.trigger",
407 keywords: &[
408 ("trigger", 3.0),
409 ("start", 1.5),
410 ("initiate", 2.5),
411 ("dream", 3.0),
412 ("begin", 1.5),
413 ("sleep", 1.5),
414 ],
415 },
416 ToolProfile {
417 tool_name: "dream.status",
418 keywords: &[
419 ("dream", 3.0),
420 ("status", 2.0),
421 ("cycle", 2.5),
422 ("sleep", 2.0),
423 ("phase", 2.0),
424 ],
425 },
426 ToolProfile {
428 tool_name: "tools.effectiveness_report",
429 keywords: &[
430 ("effectiveness", 4.0),
431 ("performance", 1.5),
432 ("report", 2.0),
433 ("efficiency", 2.0),
434 ],
435 },
436 ToolProfile {
437 tool_name: "tools.retire",
438 keywords: &[
439 ("retire", 3.0),
440 ("decommission", 3.0),
441 ("remove", 1.5),
442 ("disable", 2.0),
443 ("tool", 1.0),
444 ("sunset", 2.5),
445 ],
446 },
447 ToolProfile {
448 tool_name: "tools.list",
449 keywords: &[
450 ("tools", 3.0),
451 ("list", 2.0),
452 ("available", 2.0),
453 ("catalog", 2.5),
454 ("inventory", 2.0),
455 ("discover", 1.5),
456 ],
457 },
458 ToolProfile {
460 tool_name: "pattern.search",
461 keywords: &[
462 ("pattern", 4.0),
463 ("recurring", 3.0),
464 ("repeating", 2.5),
465 ("cycle", 2.0),
466 ("frequency", 2.0),
467 ("regularity", 2.0),
468 ],
469 },
470 ToolProfile {
471 tool_name: "salience.spotlight",
472 keywords: &[
473 ("salience", 4.0),
474 ("spotlight", 4.0),
475 ("important", 1.0),
476 ("prominent", 2.0),
477 ("notable", 2.0),
478 ("highlight", 2.0),
479 ],
480 },
481 ToolProfile {
482 tool_name: "serendipity.surface",
483 keywords: &[
484 ("serendipity", 3.0),
485 ("serendipit", 3.0),
486 ("unexpected", 2.5),
487 ("surprising", 2.5),
488 ("connection", 1.5),
489 ("surface", 1.5),
490 ],
491 },
492 ToolProfile {
494 tool_name: "constellation.detect",
495 keywords: &[
496 ("constellation", 3.0),
497 ("detect", 4.0),
498 ("cluster", 3.0),
499 ("grouping", 2.0),
500 ("density", 2.0),
501 ],
502 },
503 ToolProfile {
504 tool_name: "constellation.list",
505 keywords: &[
506 ("constellation", 3.0),
507 ("list", 4.0),
508 ("show", 2.0),
509 ("clusters", 2.0),
510 ],
511 },
512 ToolProfile {
514 tool_name: "consolidation.connect",
515 keywords: &[
516 ("connect", 2.5),
517 ("disconnected", 3.0),
518 ("link", 2.0),
519 ("propose", 2.0),
520 ("connection", 2.0),
521 ("bridge", 2.0),
522 ("unlinked", 2.5),
523 ],
524 },
525 ToolProfile {
526 tool_name: "consolidation.compress",
527 keywords: &[
528 ("compress", 3.0),
529 ("merge", 2.5),
530 ("redundancy", 3.0),
531 ("overlapping", 2.5),
532 ("reduce", 2.0),
533 ("deduplicate", 2.0),
534 ],
535 },
536 ToolProfile {
537 tool_name: "emergence.scan",
538 keywords: &[
539 ("emergence", 3.0),
540 ("emerging", 3.0),
541 ("scan", 2.0),
542 ("tag", 1.5),
543 ("topic", 2.5),
544 ("trend", 2.5),
545 ("pattern", 1.5),
546 ],
547 },
548 ToolProfile {
549 tool_name: "retention.prune",
550 keywords: &[
551 ("prune", 3.0),
552 ("forget", 2.0),
553 ("ready", 2.0),
554 ("forgettable", 3.0),
555 ("retention", 2.5),
556 ("candidate", 2.0),
557 ("cleanup", 1.5),
558 ],
559 },
560 ToolProfile {
562 tool_name: "spiral.report",
563 keywords: &[
564 ("spiral", 3.0),
565 ("autonomy", 2.5),
566 ("circular", 2.5),
567 ("thinking", 2.0),
568 ("expansion", 2.5),
569 ("novelty", 3.0),
570 ("report", 1.5),
571 ],
572 },
573 ToolProfile {
575 tool_name: "galaxy.stats",
576 keywords: &[
577 ("galaxy", 3.0),
578 ("stats", 3.0),
579 ("count", 1.5),
580 ("overview", 2.0),
581 ],
582 },
583 ToolProfile {
584 tool_name: "galaxy.export",
585 keywords: &[
586 ("export", 3.0),
587 ("backup", 2.5),
588 ("dump", 2.0),
589 ("galaxy", 2.0),
590 ("save", 1.5),
591 ],
592 },
593 ToolProfile {
594 tool_name: "galaxy.import",
595 keywords: &[
596 ("import", 3.0),
597 ("restore", 3.0),
598 ("load", 2.0),
599 ("galaxy", 2.0),
600 ("ingest", 2.5),
601 ],
602 },
603 ToolProfile {
605 tool_name: "karma.report",
606 keywords: &[
607 ("karma", 3.0),
608 ("debt", 2.5),
609 ("ledger", 2.5),
610 ("balance", 2.0),
611 ("report", 1.5),
612 ],
613 },
614 ToolProfile {
615 tool_name: "karma.history",
616 keywords: &[
617 ("karma", 2.5),
618 ("history", 3.0),
619 ("log", 2.5),
620 ("entries", 2.5),
621 ("record", 1.5),
622 ("past", 2.0),
623 ],
624 },
625 ToolProfile {
626 tool_name: "karma.clear",
627 keywords: &[
628 ("clear", 3.0),
629 ("wipe", 3.0),
630 ("reset", 2.5),
631 ("purge", 2.5),
632 ("karma", 2.0),
633 ("clean", 2.0),
634 ],
635 },
636 ToolProfile {
638 tool_name: "dharma.status",
639 keywords: &[
640 ("dharma", 3.0),
641 ("governance", 2.5),
642 ("ethics", 2.5),
643 ("status", 1.5),
644 ("rules", 1.0),
645 ],
646 },
647 ToolProfile {
648 tool_name: "dharma.rules",
649 keywords: &[
650 ("dharma", 2.5),
651 ("rules", 3.0),
652 ("governance", 2.0),
653 ("ethics", 2.0),
654 ("laws", 2.5),
655 ("principles", 2.0),
656 ],
657 },
658 ToolProfile {
659 tool_name: "dharma.audit",
660 keywords: &[
661 ("dharma", 2.0),
662 ("audit", 3.0),
663 ("governance", 2.0),
664 ("ethics", 1.5),
665 ("inspect", 2.5),
666 ("review", 2.0),
667 ],
668 },
669 ToolProfile {
670 tool_name: "dharma.profiles",
671 keywords: &[
672 ("dharma", 2.0),
673 ("profiles", 3.0),
674 ("governance", 1.5),
675 ("ethics", 1.5),
676 ("modes", 2.0),
677 ("configurations", 2.0),
678 ],
679 },
680 ToolProfile {
682 tool_name: "harmony.vector",
683 keywords: &[
684 ("harmony", 3.0),
685 ("substrate", 3.0),
686 ("hardware", 2.5),
687 ("resource", 2.0),
688 ("cpu", 2.5),
689 ("memory", 1.5),
690 ("pressure", 2.5),
691 ("thermal", 2.5),
692 ("battery", 2.5),
693 ("system", 1.0),
694 ("vector", 2.0),
695 ("status", 1.5),
696 ],
697 },
698 ToolProfile {
699 tool_name: "harmony.history",
700 keywords: &[
701 ("harmony", 2.5),
702 ("history", 3.0),
703 ("substrate", 2.0),
704 ("hardware", 2.0),
705 ("resource", 1.5),
706 ("past", 1.5),
707 ("timeline", 2.0),
708 ],
709 },
710 ToolProfile {
712 tool_name: "gnosis.status",
713 keywords: &[
714 ("gnosis", 3.0),
715 ("transparency", 3.0),
716 ("governance", 2.0),
717 ("status", 2.0),
718 ("overview", 2.0),
719 ("full", 1.5),
720 ("layers", 2.0),
721 ],
722 },
723 ToolProfile {
724 tool_name: "gnosis.history",
725 keywords: &[
726 ("gnosis", 2.5),
727 ("history", 3.0),
728 ("transparency", 2.0),
729 ("governance", 1.5),
730 ("audit", 2.0),
731 ("past", 1.5),
732 ],
733 },
734 ToolProfile {
735 tool_name: "gnosis.explain",
736 keywords: &[
737 ("gnosis", 2.0),
738 ("explain", 3.0),
739 ("why", 3.0),
740 ("blocked", 2.5),
741 ("allowed", 2.5),
742 ("verdict", 3.0),
743 ("reason", 2.5),
744 ("governance", 1.5),
745 ],
746 },
747 ToolProfile {
749 tool_name: "agent.register",
750 keywords: &[
751 ("register", 3.0),
752 ("agent", 3.0),
753 ("new", 2.0),
754 ("create", 2.0),
755 ("add", 2.0),
756 ("enroll", 2.5),
757 ],
758 },
759 ToolProfile {
760 tool_name: "agent.list",
761 keywords: &[
762 ("list", 2.5),
763 ("show", 2.0),
764 ("all", 1.5),
765 ("agents", 3.0),
766 ("roster", 2.5),
767 ],
768 },
769 ToolProfile {
770 tool_name: "agent.heartbeat",
771 keywords: &[
772 ("heartbeat", 3.0),
773 ("alive", 2.5),
774 ("ping", 2.5),
775 ("agent", 2.0),
776 ("status", 1.5),
777 ("check", 1.5),
778 ],
779 },
780 ToolProfile {
782 tool_name: "agent.trust",
783 keywords: &[
784 ("trust", 4.0),
785 ("reliability", 3.0),
786 ("confidence", 2.5),
787 ("agent", 2.0),
788 ("score", 2.0),
789 ("rating", 2.0),
790 ],
791 },
792 ToolProfile {
793 tool_name: "agent.descriptions",
794 keywords: &[
795 ("description", 4.0),
796 ("describe", 3.5),
797 ("agent", 2.0),
798 ("info", 2.0),
799 ("about", 2.0),
800 ("profile", 2.5),
801 ],
802 },
803 ToolProfile {
804 tool_name: "agent.capabilities",
805 keywords: &[
806 ("capabilities", 4.0),
807 ("capability", 3.5),
808 ("skills", 3.0),
809 ("agent", 2.0),
810 ("abilities", 2.5),
811 ("features", 2.0),
812 ],
813 },
814 ToolProfile {
815 tool_name: "agent.heartbeat.history",
816 keywords: &[
817 ("heartbeat", 3.5),
818 ("history", 3.5),
819 ("agent", 2.0),
820 ("log", 2.5),
821 ("record", 2.0),
822 ("past", 2.0),
823 ],
824 },
825 ToolProfile {
826 tool_name: "agent.deregister",
827 keywords: &[
828 ("deregister", 4.0),
829 ("unregister", 4.0),
830 ("remove", 3.0),
831 ("delete", 2.5),
832 ("agent", 2.0),
833 ("revoke", 3.0),
834 ],
835 },
836 ToolProfile {
838 tool_name: "task.distribute",
839 keywords: &[
840 ("distribute", 3.0),
841 ("assign", 2.5),
842 ("dispatch", 2.0),
843 ("task", 3.0),
844 ("delegate", 2.5),
845 ("allocate", 2.0),
846 ],
847 },
848 ToolProfile {
849 tool_name: "task.status",
850 keywords: &[
851 ("task", 2.5),
852 ("status", 3.0),
853 ("progress", 2.5),
854 ("check", 2.0),
855 ("track", 2.0),
856 ],
857 },
858 ToolProfile {
860 tool_name: "system.health",
861 keywords: &[
862 ("system", 2.5),
863 ("health", 3.0),
864 ("check", 2.0),
865 ("diagnostic", 3.0),
866 ("doctor", 2.5),
867 ("status", 1.5),
868 ],
869 },
870 ToolProfile {
871 tool_name: "system.config",
872 keywords: &[
873 ("system", 2.0),
874 ("config", 3.0),
875 ("configuration", 3.0),
876 ("settings", 2.5),
877 ("info", 2.0),
878 ("setup", 2.0),
879 ],
880 },
881 ToolProfile {
882 tool_name: "system.flush",
883 keywords: &[
884 ("flush", 3.0),
885 ("garbage", 2.5),
886 ("collect", 2.0),
887 ("gc", 3.0),
888 ("cleanup", 2.5),
889 ("purge", 1.5),
890 ("clear", 1.5),
891 ],
892 },
893 ToolProfile {
895 tool_name: "kg.extract",
896 keywords: &[
897 ("extract", 3.0),
898 ("entity", 3.0),
899 ("entities", 2.5),
900 ("relationship", 2.5),
901 ("triple", 2.5),
902 ("knowledge", 2.0),
903 ("graph", 2.0),
904 ("ner", 3.0),
905 ],
906 },
907 ToolProfile {
908 tool_name: "kg.query",
909 keywords: &[
910 ("knowledge", 2.0),
911 ("graph", 2.0),
912 ("relationship", 2.5),
913 ("entity", 2.0),
914 ("connected", 2.0),
915 ("subgraph", 3.0),
916 ("neighborhood", 2.0),
917 ],
918 },
919 ToolProfile {
920 tool_name: "kg.top",
921 keywords: &[
922 ("hub", 3.0),
923 ("god", 2.5),
924 ("node", 2.0),
925 ("top", 2.5),
926 ("ranked", 2.0),
927 ("central", 2.5),
928 ("important", 1.5),
929 ("knowledge", 1.5),
930 ("graph", 1.5),
931 ],
932 },
933 ToolProfile {
935 tool_name: "graph.walk",
936 keywords: &[
937 ("walk", 3.0),
938 ("traverse", 3.0),
939 ("bfs", 3.0),
940 ("explore", 2.0),
941 ("path", 2.0),
942 ("hop", 2.5),
943 ("follow", 2.0),
944 ("graph", 1.5),
945 ],
946 },
947 ToolProfile {
948 tool_name: "graph.community",
949 keywords: &[
950 ("community", 3.0),
951 ("cluster", 3.0),
952 ("communities", 2.5),
953 ("label", 2.0),
954 ("propagation", 2.5),
955 ("group", 2.0),
956 ("modularity", 2.5),
957 ],
958 },
959 ToolProfile {
960 tool_name: "graph.propagate",
961 keywords: &[
962 ("propagate", 3.0),
963 ("activation", 3.0),
964 ("spread", 2.5),
965 ("ripple", 2.5),
966 ("diffuse", 2.0),
967 ("energy", 2.0),
968 ("signal", 2.0),
969 ],
970 },
971 ToolProfile {
973 tool_name: "galaxy.transfer",
974 keywords: &[
975 ("transfer", 4.0),
976 ("move", 3.0),
977 ("relocate", 3.0),
978 ("migrate", 2.5),
979 ("galaxy", 1.5),
980 ],
981 },
982 ToolProfile {
983 tool_name: "galaxy.merge",
984 keywords: &[
985 ("merge", 4.0),
986 ("combine", 2.5),
987 ("unify", 2.5),
988 ("galaxy", 1.5),
989 ("absorb", 2.0),
990 ],
991 },
992 ToolProfile {
993 tool_name: "galaxy.snapshot",
994 keywords: &[
995 ("snapshot", 4.0),
996 ("backup", 3.0),
997 ("checkpoint", 2.5),
998 ("capture", 2.0),
999 ("galaxy", 1.5),
1000 ("preserve", 2.0),
1001 ],
1002 },
1003 ToolProfile {
1004 tool_name: "galaxy.restore",
1005 keywords: &[
1006 ("restore", 4.0),
1007 ("recover", 3.0),
1008 ("rollback", 3.0),
1009 ("revert", 2.5),
1010 ("galaxy", 1.5),
1011 ("undo", 2.0),
1012 ],
1013 },
1014 ToolProfile {
1016 tool_name: "galaxy.dashboard",
1017 keywords: &[
1018 ("dashboard", 4.0),
1019 ("overview", 3.5),
1020 ("summary", 3.0),
1021 ("galaxy", 2.0),
1022 ("panel", 2.5),
1023 ("report", 2.0),
1024 ],
1025 },
1026 ToolProfile {
1027 tool_name: "galaxy.backup",
1028 keywords: &[
1029 ("backup", 4.0),
1030 ("archive", 3.0),
1031 ("dump", 3.0),
1032 ("galaxy", 2.0),
1033 ("save", 2.0),
1034 ("copy", 2.0),
1035 ],
1036 },
1037 ToolProfile {
1038 tool_name: "galaxy.taxonomy",
1039 keywords: &[
1040 ("taxonomy", 4.0),
1041 ("classification", 3.0),
1042 ("categories", 2.5),
1043 ("galaxy", 2.0),
1044 ("list", 1.5),
1045 ("types", 2.0),
1046 ],
1047 },
1048 ToolProfile {
1049 tool_name: "galaxy.purge",
1050 keywords: &[
1051 ("purge", 4.0),
1052 ("clear", 3.0),
1053 ("wipe", 3.5),
1054 ("empty", 2.5),
1055 ("galaxy", 2.0),
1056 ("clean", 2.5),
1057 ],
1058 },
1059 ToolProfile {
1060 tool_name: "galaxy.health",
1061 keywords: &[
1062 ("health", 4.0),
1063 ("diagnostic", 3.0),
1064 ("checkup", 3.0),
1065 ("galaxy", 2.0),
1066 ("status", 2.0),
1067 ("integrity", 2.5),
1068 ],
1069 },
1070 ToolProfile {
1072 tool_name: "archaeology.search",
1073 keywords: &[
1074 ("archaeology", 4.0),
1075 ("excavate", 3.5),
1076 ("strata", 3.0),
1077 ("layer", 2.5),
1078 ("depth", 2.0),
1079 ("history", 2.0),
1080 ("timeline", 2.5),
1081 ("evolution", 2.0),
1082 ("oldest", 2.0),
1083 ("newest", 2.0),
1084 ],
1085 },
1086 ToolProfile {
1087 tool_name: "learning.pattern",
1088 keywords: &[
1089 ("learning", 3.0),
1090 ("pattern", 3.0),
1091 ("recurring", 2.5),
1092 ("theme", 2.5),
1093 ("frequency", 2.0),
1094 ("co-occurrence", 3.0),
1095 ("trends", 2.5),
1096 ("repeated", 2.0),
1097 ("common", 1.5),
1098 ],
1099 },
1100 ToolProfile {
1101 tool_name: "learning.suggest",
1102 keywords: &[
1103 ("suggest", 3.5),
1104 ("suggestion", 3.5),
1105 ("learn", 2.5),
1106 ("gap", 3.0),
1107 ("missing", 2.0),
1108 ("explore", 2.0),
1109 ("next", 2.0),
1110 ("recommend", 2.5),
1111 ("path", 2.0),
1112 ("advice", 2.0),
1113 ],
1114 },
1115 ToolProfile {
1117 tool_name: "bicameral.reason",
1118 keywords: &[
1119 ("bicameral", 5.0),
1120 ("hemisphere", 4.0),
1121 ("debate", 4.0),
1122 ("consensus", 3.5),
1123 ("deliberate", 3.5),
1124 ("pros", 3.0),
1125 ("cons", 3.0),
1126 ("dual", 2.5),
1127 ("perspective", 2.5),
1128 ("callosum", 4.0),
1129 ],
1130 },
1131 ToolProfile {
1132 tool_name: "bicameral.status",
1133 keywords: &[
1134 ("bicameral", 3.0),
1135 ("hemisphere", 3.5),
1136 ("callosum", 3.0),
1137 ("left", 1.5),
1138 ("right", 1.5),
1139 ("status", 2.0),
1140 ],
1141 },
1142 ToolProfile {
1143 tool_name: "reasoning.bicameral",
1144 keywords: &[
1145 ("bicameral", 3.0),
1146 ("pros", 3.5),
1147 ("cons", 3.5),
1148 ("debate", 2.5),
1149 ("perspective", 2.5),
1150 ("argument", 2.5),
1151 ("supporting", 2.0),
1152 ("opposing", 2.5),
1153 ("evidence", 2.0),
1154 ("analyze", 1.5),
1155 ],
1156 },
1157 ToolProfile {
1159 tool_name: "drive.snapshot",
1160 keywords: &[
1161 ("drive", 4.0),
1162 ("emotion", 4.0),
1163 ("motivation", 3.5),
1164 ("curiosity", 3.0),
1165 ("satisfaction", 3.0),
1166 ("caution", 2.5),
1167 ("energy", 2.0),
1168 ("mood", 3.0),
1169 ("feeling", 2.5),
1170 ],
1171 },
1172 ToolProfile {
1173 tool_name: "drive.event",
1174 keywords: &[
1175 ("drive", 3.0),
1176 ("emotion", 3.0),
1177 ("inject", 3.5),
1178 ("trigger", 2.5),
1179 ("reward", 3.0),
1180 ("frustration", 3.0),
1181 ("novelty", 2.5),
1182 ],
1183 },
1184 ToolProfile {
1185 tool_name: "think",
1186 keywords: &[
1187 ("think", 4.0),
1188 ("analyze", 3.0),
1189 ("reason", 2.5),
1190 ("consider", 2.0),
1191 ("reflect", 2.5),
1192 ("ponder", 3.0),
1193 ("contemplate", 3.0),
1194 ("insight", 2.0),
1195 ("thought", 3.0),
1196 ],
1197 },
1198 ToolProfile {
1199 tool_name: "explain",
1200 keywords: &[
1201 ("explain", 4.0),
1202 ("explanation", 3.5),
1203 ("clarify", 3.0),
1204 ("describe", 2.5),
1205 ("context", 2.0),
1206 ("related", 2.0),
1207 ("understand", 2.0),
1208 ("elaborate", 2.5),
1209 ("meaning", 2.0),
1210 ],
1211 },
1212 ToolProfile {
1214 tool_name: "pipeline.create",
1215 keywords: &[
1216 ("pipeline", 4.0),
1217 ("create", 2.5),
1218 ("build", 2.0),
1219 ("workflow", 3.0),
1220 ("steps", 2.0),
1221 ("chain", 2.0),
1222 ("sequence", 2.0),
1223 ],
1224 },
1225 ToolProfile {
1226 tool_name: "pipeline.list",
1227 keywords: &[
1228 ("pipeline", 3.5),
1229 ("list", 3.0),
1230 ("workflows", 2.5),
1231 ("show", 1.5),
1232 ("available", 2.0),
1233 ],
1234 },
1235 ToolProfile {
1236 tool_name: "pipeline.status",
1237 keywords: &[
1238 ("pipeline", 3.0),
1239 ("status", 3.0),
1240 ("check", 2.0),
1241 ("state", 2.0),
1242 ("progress", 2.5),
1243 ("running", 2.0),
1244 ],
1245 },
1246 ToolProfile {
1247 tool_name: "skill.invoke",
1248 keywords: &[
1249 ("skill", 4.0),
1250 ("invoke", 3.5),
1251 ("execute", 2.5),
1252 ("run", 2.0),
1253 ("call", 2.0),
1254 ("trigger", 2.0),
1255 ("ability", 2.5),
1256 ],
1257 },
1258 ToolProfile {
1259 tool_name: "skill.list",
1260 keywords: &[
1261 ("skill", 3.5),
1262 ("list", 3.0),
1263 ("abilities", 2.5),
1264 ("available", 2.0),
1265 ("show", 1.5),
1266 ("capabilities", 2.0),
1267 ],
1268 },
1269 ToolProfile {
1271 tool_name: "anomaly.detect",
1272 keywords: &[
1273 ("anomaly", 4.0),
1274 ("detect", 3.0),
1275 ("outlier", 3.5),
1276 ("unusual", 2.5),
1277 ("abnormal", 3.0),
1278 ("strange", 2.0),
1279 ("irregular", 2.5),
1280 ("z-score", 3.0),
1281 ],
1282 },
1283 ToolProfile {
1284 tool_name: "state.snapshot",
1285 keywords: &[
1286 ("snapshot", 4.0),
1287 ("capture", 2.5),
1288 ("state", 2.5),
1289 ("checkpoint", 3.0),
1290 ("preserve", 2.0),
1291 ("record", 2.0),
1292 ],
1293 },
1294 ToolProfile {
1295 tool_name: "state.revert",
1296 keywords: &[
1297 ("revert", 4.0),
1298 ("rollback", 3.5),
1299 ("restore", 3.0),
1300 ("previous", 2.5),
1301 ("undo", 2.5),
1302 ("go back", 2.0),
1303 ("state", 2.0),
1304 ],
1305 },
1306 ToolProfile {
1308 tool_name: "correlation.analyze",
1309 keywords: &[
1310 ("correlation", 4.0),
1311 ("analyze", 2.0),
1312 ("co-occurrence", 3.0),
1313 ("phi", 2.5),
1314 ("relationship", 2.0),
1315 ("statistical", 2.5),
1316 ("connect", 1.5),
1317 ("associate", 1.5),
1318 ],
1319 },
1320 ToolProfile {
1321 tool_name: "god.nodes",
1322 keywords: &[
1323 ("god", 3.5),
1324 ("nodes", 3.0),
1325 ("hub", 3.0),
1326 ("central", 2.5),
1327 ("important", 2.0),
1328 ("connector", 3.0),
1329 ("cross-galaxy", 3.0),
1330 ("entity", 2.0),
1331 ],
1332 },
1333 ToolProfile {
1335 tool_name: "anti_loop.check",
1336 keywords: &[
1337 ("loop", 4.0),
1338 ("anti", 2.5),
1339 ("repetitive", 3.0),
1340 ("duplicate", 3.0),
1341 ("stuck", 3.0),
1342 ("cycle", 2.5),
1343 ("repeated", 2.5),
1344 ("burst", 2.0),
1345 ],
1346 },
1347 ToolProfile {
1348 tool_name: "boundary.enforce",
1349 keywords: &[
1350 ("boundary", 4.0),
1351 ("enforce", 3.5),
1352 ("limit", 3.0),
1353 ("violation", 3.0),
1354 ("overflow", 3.0),
1355 ("constraint", 2.5),
1356 ("check", 2.0),
1357 ("resource", 2.0),
1358 ("sprawl", 2.5),
1359 ],
1360 },
1361 ToolProfile {
1363 tool_name: "association.mine",
1364 keywords: &[
1365 ("cross", 5.0),
1366 ("galaxy", 4.0),
1367 ("association", 3.0),
1368 ("mine", 3.0),
1369 ("overlap", 2.5),
1370 ("keyword", 2.0),
1371 ("propose", 2.0),
1372 ("link", 2.0),
1373 ],
1374 },
1375 ToolProfile {
1376 tool_name: "pattern.detect",
1377 keywords: &[
1378 ("pattern", 4.0),
1379 ("detect", 3.5),
1380 ("structural", 3.0),
1381 ("hub", 3.0),
1382 ("bridge", 3.0),
1383 ("chain", 2.5),
1384 ("graph", 2.0),
1385 ("topology", 2.5),
1386 ],
1387 },
1388 ToolProfile {
1389 tool_name: "emergence.report",
1390 keywords: &[
1391 ("emergence", 4.0),
1392 ("report", 3.0),
1393 ("tag", 2.5),
1394 ("frequency", 2.5),
1395 ("distribution", 2.0),
1396 ("trend", 2.0),
1397 ("emerging", 3.0),
1398 ("dominant", 2.0),
1399 ],
1400 },
1401 ToolProfile {
1402 tool_name: "network.stats",
1403 keywords: &[
1404 ("network", 4.0),
1405 ("stats", 3.0),
1406 ("density", 3.0),
1407 ("degree", 2.5),
1408 ("edge", 2.0),
1409 ("node", 2.0),
1410 ("global", 2.0),
1411 ("graph", 2.0),
1412 ],
1413 },
1414 ToolProfile {
1415 tool_name: "network.centrality",
1416 keywords: &[
1417 ("centrality", 4.0),
1418 ("central", 3.0),
1419 ("degree", 3.0),
1420 ("important", 2.0),
1421 ("influential", 2.5),
1422 ("hub", 2.0),
1423 ("rank", 2.0),
1424 ("top", 2.0),
1425 ],
1426 },
1427 ToolProfile {
1428 tool_name: "network.clusters",
1429 keywords: &[
1430 ("cluster", 4.0),
1431 ("clusters", 3.0),
1432 ("component", 3.0),
1433 ("connected", 2.5),
1434 ("group", 2.0),
1435 ("isolate", 2.0),
1436 ("subgraph", 2.5),
1437 ],
1438 },
1439 ToolProfile {
1441 tool_name: "smarana.status",
1442 keywords: &[
1443 ("smarana", 5.0),
1444 ("retention", 4.0),
1445 ("recall", 3.0),
1446 ("score", 2.0),
1447 ("memory", 1.5),
1448 ("forgetting", 2.5),
1449 ],
1450 },
1451 ToolProfile {
1452 tool_name: "smarana.trace",
1453 keywords: &[
1454 ("smarana", 4.0),
1455 ("trace", 3.5),
1456 ("decay", 3.0),
1457 ("retention", 3.0),
1458 ("over", 2.0),
1459 ("time", 1.5),
1460 ("history", 2.0),
1461 ],
1462 },
1463 ToolProfile {
1464 tool_name: "apotheosis.check",
1465 keywords: &[
1466 ("apotheosis", 5.0),
1467 ("self", 2.5),
1468 ("improvement", 3.5),
1469 ("trend", 3.0),
1470 ("progress", 2.5),
1471 ("check", 2.0),
1472 ("score", 2.0),
1473 ],
1474 },
1475 ToolProfile {
1476 tool_name: "citta.history",
1477 keywords: &[
1478 ("citta", 4.0),
1479 ("history", 3.5),
1480 ("heartbeat", 3.0),
1481 ("valence", 2.5),
1482 ("past", 2.0),
1483 ("recent", 2.0),
1484 ("consciousness", 2.5),
1485 ],
1486 },
1487 ToolProfile {
1488 tool_name: "dream.analyze",
1489 keywords: &[
1490 ("dream", 4.0),
1491 ("analyze", 3.5),
1492 ("analysis", 3.0),
1493 ("consolidation", 2.5),
1494 ("quality", 2.5),
1495 ("sleep", 2.0),
1496 ("cycle", 2.0),
1497 ],
1498 },
1499 ToolProfile {
1500 tool_name: "consciousness.depth",
1501 keywords: &[
1502 ("consciousness", 4.0),
1503 ("depth", 4.0),
1504 ("deep", 3.0),
1505 ("measure", 2.5),
1506 ("awareness", 2.5),
1507 ("state", 2.0),
1508 ("level", 2.0),
1509 ],
1510 },
1511 ToolProfile {
1513 tool_name: "memory.sort",
1514 keywords: &[
1515 ("sort", 4.0),
1516 ("order", 3.5),
1517 ("arrange", 3.0),
1518 ("rank", 2.5),
1519 ("by", 1.5),
1520 ("importance", 2.0),
1521 ("recency", 2.0),
1522 ("memory", 1.5),
1523 ],
1524 },
1525 ToolProfile {
1526 tool_name: "memory.filter",
1527 keywords: &[
1528 ("filter", 4.0),
1529 ("where", 2.5),
1530 ("match", 2.0),
1531 ("criteria", 3.0),
1532 ("condition", 2.5),
1533 ("tag", 2.0),
1534 ("importance", 1.5),
1535 ("memory", 1.5),
1536 ],
1537 },
1538 ToolProfile {
1539 tool_name: "memory.deduplicate",
1540 keywords: &[
1541 ("deduplicate", 4.0),
1542 ("dedup", 4.0),
1543 ("duplicate", 3.5),
1544 ("unique", 2.5),
1545 ("distinct", 3.0),
1546 ("remove", 2.0),
1547 ("redundant", 3.0),
1548 ("memory", 1.5),
1549 ],
1550 },
1551 ToolProfile {
1552 tool_name: "memory.export",
1553 keywords: &[
1554 ("export", 4.0),
1555 ("download", 3.0),
1556 ("dump", 3.0),
1557 ("extract", 2.5),
1558 ("format", 2.0),
1559 ("csv", 3.5),
1560 ("markdown", 3.0),
1561 ("memory", 1.5),
1562 ],
1563 },
1564 ToolProfile {
1566 tool_name: "homeostasis.check",
1567 keywords: &[
1568 ("homeostasis", 5.0),
1569 ("check", 3.0),
1570 ("balance", 3.5),
1571 ("equilibrium", 3.0),
1572 ("health", 2.5),
1573 ("metrics", 3.0),
1574 ("vitals", 3.0),
1575 ("system", 1.5),
1576 ],
1577 },
1578 ToolProfile {
1579 tool_name: "homeostasis.adjust",
1580 keywords: &[
1581 ("homeostasis", 4.0),
1582 ("adjust", 3.5),
1583 ("tune", 3.0),
1584 ("rebalance", 3.5),
1585 ("weight", 3.0),
1586 ("simulate", 2.5),
1587 ("recalibrate", 3.0),
1588 ],
1589 },
1590 ToolProfile {
1591 tool_name: "homeostasis.history",
1592 keywords: &[
1593 ("homeostasis", 4.0),
1594 ("history", 3.5),
1595 ("past", 2.5),
1596 ("trend", 3.0),
1597 ("samples", 3.0),
1598 ("readings", 2.5),
1599 ("timeline", 2.0),
1600 ],
1601 },
1602 ToolProfile {
1603 tool_name: "homeostasis.alerts",
1604 keywords: &[
1605 ("homeostasis", 4.0),
1606 ("alert", 4.0),
1607 ("alerts", 4.0),
1608 ("warning", 3.5),
1609 ("critical", 3.0),
1610 ("notify", 2.5),
1611 ("threshold", 2.5),
1612 ("triggered", 2.0),
1613 ],
1614 },
1615 ToolProfile {
1617 tool_name: "reflex.dispatch",
1618 keywords: &[
1619 ("reflex", 5.0),
1620 ("dispatch", 5.0),
1621 ("trigger", 4.0),
1622 ("invoke", 3.0),
1623 ("fire", 3.0),
1624 ("handler", 2.5),
1625 ("emergency", 2.0),
1626 ("e_stop", 3.5),
1627 ("estop", 3.5),
1628 ("safety", 2.0),
1629 ("actuator", 2.0),
1630 ],
1631 },
1632 ToolProfile {
1633 tool_name: "reflex.status",
1634 keywords: &[
1635 ("reflex", 5.0),
1636 ("status", 4.0),
1637 ("table", 3.0),
1638 ("handler", 2.5),
1639 ("registered", 2.5),
1640 ("safety_mask", 3.0),
1641 ("dispatch_count", 3.0),
1642 ("builtins", 2.0),
1643 ],
1644 },
1645 ToolProfile {
1647 tool_name: "workspace.spotlight",
1648 keywords: &[
1649 ("spotlight", 5.0),
1650 ("attention", 4.0),
1651 ("focus", 3.0),
1652 ("arbitration", 3.5),
1653 ("workspace", 3.0),
1654 ("current", 2.0),
1655 ("holder", 2.5),
1656 ("salience", 2.5),
1657 ("who", 1.5),
1658 ("winning", 2.5),
1659 ],
1660 },
1661 ToolProfile {
1662 tool_name: "workspace.events",
1663 keywords: &[
1664 ("workspace", 4.0),
1665 ("events", 5.0),
1666 ("backlog", 4.0),
1667 ("history", 2.5),
1668 ("log", 2.0),
1669 ],
1670 },
1671 ToolProfile {
1672 tool_name: "workspace.publish",
1673 keywords: &[
1674 ("workspace", 4.0),
1675 ("publish", 5.0),
1676 ("broadcast", 4.0),
1677 ("emit", 3.5),
1678 ("send", 2.5),
1679 ("event", 3.0),
1680 ("post", 2.5),
1681 ("notify", 2.0),
1682 ("submit", 2.5),
1683 ],
1684 },
1685 ToolProfile {
1686 tool_name: "workspace.stats",
1687 keywords: &[
1688 ("workspace", 4.0),
1689 ("stats", 5.0),
1690 ("statistics", 4.5),
1691 ("transfers", 3.0),
1692 ("arbitration", 2.5),
1693 ("published", 3.0),
1694 ("count", 2.0),
1695 ("summary", 2.5),
1696 ],
1697 },
1698 ToolProfile {
1700 tool_name: "timescale.status",
1701 keywords: &[
1702 ("timescale", 5.0),
1703 ("status", 4.0),
1704 ("tier", 3.0),
1705 ("tiers", 3.0),
1706 ("bus", 2.5),
1707 ("brain_wave", 3.0),
1708 ("active", 2.5),
1709 ("hooks", 2.0),
1710 ("interval", 2.0),
1711 ("budget", 2.0),
1712 ],
1713 },
1714 ToolProfile {
1715 tool_name: "timescale.hooks",
1716 keywords: &[
1717 ("timescale", 4.0),
1718 ("hooks", 5.0),
1719 ("hook", 4.0),
1720 ("list", 2.5),
1721 ("stats", 2.5),
1722 ("performance", 2.5),
1723 ("tick", 3.0),
1724 ("timeout", 2.5),
1725 ("duration", 2.0),
1726 ("callback", 2.0),
1727 ],
1728 },
1729 ToolProfile {
1731 tool_name: "selfmodel.forecast",
1732 keywords: &[
1733 ("forecast", 5.0),
1734 ("predict", 4.0),
1735 ("prediction", 4.0),
1736 ("project", 3.0),
1737 ("projection", 3.0),
1738 ("extrapolate", 4.0),
1739 ("trend", 3.0),
1740 ("outlook", 3.0),
1741 ("selfmodel", 5.0),
1742 ("introspect", 3.0),
1743 ("horizon", 2.5),
1744 ("metric", 2.0),
1745 ],
1746 },
1747 ToolProfile {
1748 tool_name: "selfmodel.alerts",
1749 keywords: &[
1750 ("alert", 5.0),
1751 ("alerts", 5.0),
1752 ("warning", 3.5),
1753 ("warnings", 3.5),
1754 ("critical", 3.5),
1755 ("threshold", 3.0),
1756 ("breach", 3.0),
1757 ("exceed", 2.5),
1758 ("danger", 3.0),
1759 ("selfmodel", 5.0),
1760 ("introspect", 3.0),
1761 ],
1762 },
1763 ToolProfile {
1764 tool_name: "selfmodel.snapshot",
1765 keywords: &[
1766 ("snapshot", 5.0),
1767 ("selfmodel", 5.0),
1768 ("introspect", 4.0),
1769 ("introspection", 4.0),
1770 ("overview", 3.0),
1771 ("confidence", 3.0),
1772 ("conservative", 2.5),
1773 ],
1774 },
1775 ToolProfile {
1777 tool_name: "friction.log",
1778 keywords: &[
1779 ("friction", 5.0),
1780 ("log", 3.0),
1781 ("report", 2.5),
1782 ("issue", 3.5),
1783 ("problem", 3.0),
1784 ("bug", 3.0),
1785 ("complaint", 3.0),
1786 ("annoying", 2.5),
1787 ("broken", 2.5),
1788 ("wrong", 2.0),
1789 ],
1790 },
1791 ToolProfile {
1792 tool_name: "friction.review",
1793 keywords: &[
1794 ("friction", 4.5),
1795 ("review", 4.0),
1796 ("issues", 3.5),
1797 ("problems", 3.0),
1798 ("patterns", 2.5),
1799 ("summary", 2.5),
1800 ("analyze", 2.0),
1801 ("frictions", 4.0),
1802 ],
1803 },
1804 ToolProfile {
1805 tool_name: "improve.proposals",
1806 keywords: &[
1807 ("improve", 5.0),
1808 ("improvement", 5.0),
1809 ("improvements", 5.0),
1810 ("proposal", 4.0),
1811 ("proposals", 4.0),
1812 ("suggest", 3.0),
1813 ("suggestions", 3.0),
1814 ("fix", 2.5),
1815 ("friction", 2.0),
1816 ("upgrade", 3.0),
1817 ("enhance", 2.5),
1818 ("better", 2.0),
1819 ],
1820 },
1821 ToolProfile {
1822 tool_name: "redteam.proposals",
1823 keywords: &[
1824 ("redteam", 5.0),
1825 ("red", 2.0),
1826 ("team", 2.0),
1827 ("adversarial", 5.0),
1828 ("attack", 4.5),
1829 ("vulnerability", 4.5),
1830 ("security", 4.0),
1831 ("exploit", 4.0),
1832 ("breach", 3.5),
1833 ("pentest", 4.5),
1834 ("penetrate", 3.5),
1835 ("break", 3.0),
1836 ("threat", 3.5),
1837 ("probe", 3.0),
1838 ("audit", 2.5),
1839 ],
1840 },
1841 ToolProfile {
1843 tool_name: "sensor.list",
1844 keywords: &[
1845 ("sensor", 5.0),
1846 ("sensors", 5.0),
1847 ("list", 3.0),
1848 ("hardware", 3.0),
1849 ("devices", 2.5),
1850 ("thermal", 2.0),
1851 ("battery", 2.0),
1852 ],
1853 },
1854 ToolProfile {
1855 tool_name: "sensor.read",
1856 keywords: &[
1857 ("read", 4.0),
1858 ("sensor", 4.0),
1859 ("temperature", 3.5),
1860 ("value", 3.0),
1861 ("measure", 3.0),
1862 ("probe", 2.5),
1863 ],
1864 },
1865 ToolProfile {
1866 tool_name: "sensor.poll",
1867 keywords: &[
1868 ("poll", 5.0),
1869 ("sample", 4.0),
1870 ("all", 2.5),
1871 ("sensors", 3.0),
1872 ("readings", 3.5),
1873 ("collect", 2.5),
1874 ],
1875 },
1876 ToolProfile {
1877 tool_name: "sensor.history",
1878 keywords: &[
1879 ("history", 5.0),
1880 ("past", 3.0),
1881 ("readings", 3.5),
1882 ("recent", 3.0),
1883 ("log", 2.5),
1884 ("timeseries", 3.5),
1885 ],
1886 },
1887 ToolProfile {
1888 tool_name: "actuator.list",
1889 keywords: &[
1890 ("actuator", 5.0),
1891 ("actuators", 5.0),
1892 ("motor", 3.0),
1893 ("relay", 3.0),
1894 ("output", 2.5),
1895 ],
1896 },
1897 ToolProfile {
1898 tool_name: "actuator.command",
1899 keywords: &[
1900 ("command", 4.5),
1901 ("send", 3.5),
1902 ("actuator", 4.0),
1903 ("motor", 3.0),
1904 ("drive", 3.0),
1905 ("control", 3.5),
1906 ("set", 2.0),
1907 ],
1908 },
1909 ToolProfile {
1910 tool_name: "actuator.estop",
1911 keywords: &[
1912 ("estop", 5.0),
1913 ("emergency", 5.0),
1914 ("stop", 4.0),
1915 ("halt", 4.0),
1916 ("abort", 3.5),
1917 ("shutdown", 3.0),
1918 ],
1919 },
1920 ToolProfile {
1921 tool_name: "reflex.list",
1922 keywords: &[
1923 ("reflex", 5.0),
1924 ("reflexes", 5.0),
1925 ("rules", 3.0),
1926 ("trigger", 2.5),
1927 ],
1928 },
1929 ToolProfile {
1930 tool_name: "reflex.add",
1931 keywords: &[
1932 ("add", 3.5),
1933 ("reflex", 4.5),
1934 ("rule", 4.0),
1935 ("create", 3.0),
1936 ("threshold", 3.5),
1937 ("trigger", 3.0),
1938 ],
1939 },
1940 ToolProfile {
1941 tool_name: "reflex.evaluate",
1942 keywords: &[
1943 ("evaluate", 5.0),
1944 ("check", 3.0),
1945 ("reflex", 4.0),
1946 ("trigger", 3.5),
1947 ("fire", 3.0),
1948 ("respond", 2.5),
1949 ],
1950 },
1951 ToolProfile {
1952 tool_name: "sensorimotor.scan",
1953 keywords: &[
1954 ("sensorimotor", 6.0),
1955 ("scan", 4.0),
1956 ("poll", 3.5),
1957 ("reflex", 3.0),
1958 ("autonomous", 3.0),
1959 ("embodiment", 4.0),
1960 ("cycle", 2.5),
1961 ("self-regulate", 3.0),
1962 ],
1963 },
1964 ToolProfile {
1966 tool_name: "gnosis",
1967 keywords: &[
1968 ("help", 2.0),
1969 ("discover", 2.0),
1970 ("what", 1.5),
1971 ("can", 1.0),
1972 ("do", 1.0),
1973 ("status", 1.5),
1974 ("overview", 2.0),
1975 ("system", 1.0),
1976 ],
1977 },
1978 ToolProfile {
1980 tool_name: "speculative.decode",
1981 keywords: &[
1982 ("speculative", 5.0),
1983 ("decode", 4.0),
1984 ("draft", 3.0),
1985 ("verify", 2.5),
1986 ("accelerate", 3.0),
1987 ("speedup", 3.0),
1988 ("fast", 2.0),
1989 ("infer", 2.0),
1990 ("generate", 1.5),
1991 ],
1992 },
1993 ToolProfile {
1994 tool_name: "speculative.stats",
1995 keywords: &[
1996 ("speculative", 4.0),
1997 ("acceptance", 3.0),
1998 ("speedup", 3.0),
1999 ("draft", 2.0),
2000 ("latency", 2.0),
2001 ("tokens", 2.0),
2002 ],
2003 },
2004 ToolProfile {
2006 tool_name: "meta.enhance",
2007 keywords: &[
2008 ("enhance", 5.0),
2009 ("grounding", 4.0),
2010 ("grounded", 4.0),
2011 ("rag", 4.0),
2012 ("self-correct", 4.0),
2013 ("selfcorrect", 4.0),
2014 ("ensemble", 3.5),
2015 ("improve", 3.0),
2016 ("cognitive", 3.0),
2017 ("meta", 2.5),
2018 ("harness", 3.0),
2019 ("augment", 2.5),
2020 ("refine", 2.0),
2021 ],
2022 },
2023 ToolProfile {
2024 tool_name: "meta.stats",
2025 keywords: &[
2026 ("meta", 3.0),
2027 ("harness", 3.0),
2028 ("enhancement", 3.0),
2029 ("improvement", 3.0),
2030 ("enhance", 2.0),
2031 ("stats", 2.0),
2032 ],
2033 },
2034 ToolProfile {
2036 tool_name: "dense.encode",
2037 keywords: &[
2038 ("dense", 5.0),
2039 ("compress", 4.0),
2040 ("compression", 4.0),
2041 ("encode", 3.5),
2042 ("encoding", 3.5),
2043 ("token", 2.5),
2044 ("compact", 3.0),
2045 ("shrink", 2.5),
2046 ("cjk", 3.0),
2047 ],
2048 },
2049 ToolProfile {
2050 tool_name: "dense.decode",
2051 keywords: &[
2052 ("decode", 4.0),
2053 ("decompress", 4.0),
2054 ("expand", 3.0),
2055 ("restore", 2.5),
2056 ("dense", 2.0),
2057 ],
2058 },
2059 ToolProfile {
2061 tool_name: "transaction.begin",
2062 keywords: &[
2063 ("transaction", 5.0),
2064 ("begin", 4.0),
2065 ("start", 3.0),
2066 ("snapshot", 3.5),
2067 ("checkpoint", 3.0),
2068 ("atomic", 3.0),
2069 ],
2070 },
2071 ToolProfile {
2072 tool_name: "transaction.commit",
2073 keywords: &[
2074 ("transaction", 5.0),
2075 ("commit", 5.0),
2076 ("finalize", 3.5),
2077 ("confirm", 3.0),
2078 ("keep", 2.5),
2079 ("persist", 3.0),
2080 ],
2081 },
2082 ToolProfile {
2083 tool_name: "transaction.rollback",
2084 keywords: &[
2085 ("transaction", 5.0),
2086 ("rollback", 5.0),
2087 ("revert", 4.0),
2088 ("undo", 4.0),
2089 ("restore", 3.5),
2090 ("abort", 3.5),
2091 ("discard", 3.0),
2092 ],
2093 },
2094 ToolProfile {
2096 tool_name: "imagine.scenario",
2097 keywords: &[
2098 ("imagine", 5.0),
2099 ("scenario", 5.0),
2100 ("scenarios", 4.5),
2101 ("plan", 3.0),
2102 ("contingency", 4.0),
2103 ("what-if", 4.0),
2104 ("possibility", 3.5),
2105 ("options", 2.5),
2106 ("alternatives", 3.0),
2107 ("brainstorm", 3.5),
2108 ("envision", 3.5),
2109 ],
2110 },
2111 ToolProfile {
2112 tool_name: "imagine.predict",
2113 keywords: &[
2114 ("predict", 5.0),
2115 ("outcome", 4.0),
2116 ("consequence", 4.0),
2117 ("forecast", 3.0),
2118 ("expect", 3.0),
2119 ("result", 2.5),
2120 ("happen", 3.5),
2121 ("would", 2.5),
2122 ("if", 1.5),
2123 ("imagine", 2.0),
2124 ],
2125 },
2126 ToolProfile {
2127 tool_name: "imagine.reflect",
2128 keywords: &[
2129 ("reflect", 5.0),
2130 ("counterfactual", 5.0),
2131 ("regret", 4.0),
2132 ("alternative", 3.5),
2133 ("should", 3.0),
2134 ("instead", 3.0),
2135 ("what-if", 3.0),
2136 ("reconsider", 4.0),
2137 ("retrospect", 3.5),
2138 ("lesson", 3.0),
2139 ("counter", 2.5),
2140 ("factual", 2.5),
2141 ],
2142 },
2143 ToolProfile {
2145 tool_name: "nlu.shadow_report",
2146 keywords: &[
2147 ("shadow", 4.0),
2148 ("disagreement", 4.0),
2149 ("nlu", 3.0),
2150 ("router", 3.0),
2151 ("embedding", 2.5),
2152 ("tfidf", 2.5),
2153 ("tf-idf", 2.5),
2154 ("oats", 3.0),
2155 ("promotion", 2.5),
2156 ("routing", 2.0),
2157 ],
2158 },
2159];
2160
2161const STOPWORDS: &[&str] = &[
2164 "a", "an", "the", "this", "that", "these", "those", "i", "me", "my", "you", "your", "yours", "it", "its", "we", "our", "ours", "they", "them",
2168 "their", "theirs", "he", "him", "his", "she", "her", "hers", "is", "are", "was", "were", "be", "been", "being", "am", "have", "has", "had", "will", "would",
2170 "could", "should", "shall", "must", "in", "on", "at", "to", "for", "of", "with", "by", "from", "into", "about", "over", "under",
2172 "through", "between", "among", "during", "before", "after", "above", "below",
2173 "and", "but", "or", "nor", "so", "yet", "not", "no", "yes", "if", "else", "because", "as", "until", "while", "although", "though", "since", "unless",
2177 "whether", "up", "down", "out", "off", "again", "further", "then", "once", "here", "there", "when",
2179 "where", "why", "how", "all", "any", "both", "each", "few", "more", "most", "other", "some", "such", "only", "own",
2181 "same", "than", "too", "very", "just", "also", "now",
2183];
2184
2185const E_DROPPING_BASES: &[&str] = &[
2189 "activat",
2190 "allocat",
2191 "arrang",
2192 "associat",
2193 "becom",
2194 "calculat",
2195 "chang",
2196 "clos",
2197 "cit",
2198 "configur",
2199 "consolidat",
2200 "continu",
2201 "creat",
2202 "delegat",
2203 "delet",
2204 "demonstrat",
2205 "downgrad",
2206 "encourag",
2207 "engag",
2208 "ensur",
2209 "enumerat",
2210 "evaluat",
2211 "exchang",
2212 "exclud",
2213 "explor",
2214 "fac",
2215 "generat",
2216 "giv",
2217 "improv",
2218 "includ",
2219 "leav",
2220 "lik",
2221 "mak",
2222 "manag",
2223 "measur",
2224 "merg",
2225 "mov",
2226 "navigat",
2227 "notic",
2228 "operat",
2229 "practic",
2230 "relat",
2231 "remov",
2232 "restor",
2233 "sav",
2234 "simulat",
2235 "stor",
2236 "tak",
2237 "updat",
2238 "upgrad",
2239 "us",
2240 "validat",
2241 "writ",
2242];
2243
2244fn stem(word: &str) -> String {
2248 let w = word.to_lowercase();
2249
2250 if w.ends_with("ies") && w.len() > 3 {
2252 let base = &w[..w.len() - 3];
2253 return format!("{base}y");
2254 }
2255
2256 if w.ends_with("ing") && w.len() > 4 {
2258 let base = &w[..w.len() - 3];
2259 if let Some(last) = base.chars().last() {
2263 let is_double_consonant = base.chars().rev().nth(1) == Some(last);
2264 if is_double_consonant {
2265 return base[..base.len() - last.len_utf8()].to_string();
2266 }
2267 }
2268 if E_DROPPING_BASES.binary_search(&base).is_ok() {
2270 return format!("{base}e");
2271 }
2272 return base.to_string();
2273 }
2274
2275 if w.ends_with("ed") && w.len() > 3 {
2277 let base = &w[..w.len() - 2];
2278 if E_DROPPING_BASES.binary_search(&base).is_ok() {
2280 return format!("{base}e");
2281 }
2282 return base.to_string();
2283 }
2284
2285 if w.ends_with("es") && w.len() > 3 {
2287 let base = &w[..w.len() - 2];
2288 if base.ends_with("ch")
2290 || base.ends_with("sh")
2291 || base.ends_with('s')
2292 || base.ends_with('x')
2293 || base.ends_with('z')
2294 {
2295 return base.to_string();
2296 }
2297 return w[..w.len() - 1].to_string();
2298 }
2299
2300 if w.ends_with('s') && w.len() > 2 && !w.ends_with("ss") {
2302 return w[..w.len() - 1].to_string();
2303 }
2304
2305 w
2306}
2307
2308fn tokenize(text: &str) -> Vec<String> {
2311 text.split(|c: char| !c.is_alphanumeric())
2312 .filter(|s| !s.is_empty())
2313 .map(str::to_lowercase)
2314 .filter(|s| !STOPWORDS.contains(&s.as_str()))
2315 .map(|s| stem(&s))
2316 .collect()
2317}
2318
2319fn term_frequencies(tokens: &[String]) -> AHashMap<String, f64> {
2321 let mut tf = AHashMap::new();
2322 for token in tokens {
2323 *tf.entry(token.clone()).or_insert(0.0) += 1.0;
2324 }
2325 tf
2326}
2327
2328fn cosine_similarity(input_tf: &AHashMap<String, f64>, profile: &ToolProfile) -> f64 {
2334 let mut dot_product = 0.0;
2335 let mut profile_norm_sq = 0.0;
2336
2337 for (term, weight) in profile.keywords {
2338 profile_norm_sq += weight * weight;
2339 let stemmed_term = stem(term);
2340 if let Some(&freq) = input_tf.get(&stemmed_term) {
2341 dot_product += freq * weight;
2342 }
2343 }
2344
2345 if profile_norm_sq == 0.0 {
2346 return 0.0;
2347 }
2348
2349 let input_norm: f64 = input_tf.values().map(|v| v * v).sum::<f64>().sqrt();
2350 if input_norm == 0.0 {
2351 return 0.0;
2352 }
2353
2354 dot_product / (input_norm * profile_norm_sq.sqrt())
2355}
2356
2357pub const PREFIX_ROUTES: &[(&str, &str, f64)] = &[
2365 ("remember", "memory.create", 1.5),
2366 ("store", "memory.create", 1.5),
2367 ("save", "memory.create", 1.5),
2368 ("memorize", "memory.create", 1.5),
2369 ("resume", "session.continuity", 1.5),
2370 ("recall", "memory.search", 1.5),
2371 ("search", "memory.search", 1.3),
2372 ("find", "memory.search", 1.4),
2373 ("list", "memory.list", 1.3),
2374 ("delete", "memory.delete", 1.5),
2375 ("remove", "memory.delete", 1.3),
2376 ("forget", "memory.delete", 1.5),
2377 ("count", "memory.count", 1.5),
2378 ("show", "gnosis", 1.0),
2379 ("spotlight", "workspace.spotlight", 1.5),
2380 ("publish", "workspace.publish", 1.5),
2381 ("broadcast", "workspace.publish", 1.4),
2382 ("forecast", "selfmodel.forecast", 1.5),
2383 ("deliberate", "bicameral.reason", 1.3),
2384 ("drive", "drive.snapshot", 1.5),
2385 ("emotion", "drive.snapshot", 1.4),
2386 ("adversarial", "redteam.proposals", 1.5),
2387 ("redteam", "redteam.proposals", 1.5),
2388 ("pentest", "redteam.proposals", 1.5),
2389 ("friction", "friction.log", 1.3),
2390 ("log", "friction.log", 1.4),
2391 ("sensor", "sensor.list", 1.5),
2392 ("actuator", "actuator.list", 1.5),
2393 ("estop", "actuator.estop", 1.5),
2394 ("emergency", "actuator.estop", 1.3),
2395 ("sensorimotor", "sensorimotor.scan", 1.5),
2396 ("imagine", "imagine.scenario", 1.5),
2397 ("envision", "imagine.scenario", 1.4),
2398 ("brainstorm", "imagine.scenario", 1.3),
2399 ("counterfactual", "imagine.reflect", 1.5),
2400];
2401
2402pub const PHRASE_ROUTES: &[(&str, &str, f64)] = &[
2409 ("what do you remember about", "memory.search", 1.5),
2410 ("what did we decide about", "memory.search", 1.5),
2411 ("do you remember", "memory.search", 1.4),
2412 ("look up", "memory.search", 1.4),
2413 ("where were we", "session.continuity", 1.5),
2418 ("where did we leave off", "session.continuity", 1.5),
2419 ("what did we decide last", "session.continuity", 1.5),
2420 ("continue from", "session.continuity", 1.4),
2421 ("pick up where", "session.continuity", 1.4),
2422];
2423
2424#[must_use]
2427pub fn classify(text: &str) -> (&'static str, f64) {
2428 let (tool, confidence, _) = classify_with_alternative(text);
2429 (tool, confidence)
2430}
2431
2432#[must_use]
2439pub fn classify_with_alternative(text: &str) -> (&'static str, f64, Option<(&'static str, f64)>) {
2440 let lower = text.to_lowercase();
2441 if lower.trim().is_empty() {
2442 return ("gnosis", 0.0, None);
2443 }
2444
2445 let tokens = tokenize(&lower);
2446 if tokens.is_empty() {
2447 return ("gnosis", 0.0, None);
2448 }
2449
2450 let input_tf = term_frequencies(&tokens);
2451
2452 let probe = lower.trim_start();
2457 if let Some((_, tool, _)) = PHRASE_ROUTES
2458 .iter()
2459 .find(|(phrase, _, _)| probe.starts_with(phrase))
2460 {
2461 return (tool, 1.0, None);
2462 }
2463
2464 let first_word = probe.split_whitespace().next().unwrap_or("");
2466 let prefix_bonus: Option<(&str, f64)> = PREFIX_ROUTES
2467 .iter()
2468 .find(|(verb, _, _)| *verb == first_word)
2469 .map(|(_, tool, bonus)| (*tool, *bonus));
2470
2471 let mut best_tool = "gnosis";
2472 let mut best_score = 0.0;
2473 let mut second: Option<(&'static str, f64)> = None;
2474
2475 for profile in TOOL_PROFILES {
2476 let mut score = cosine_similarity(&input_tf, profile);
2477 if let Some((bonus_tool, bonus)) = prefix_bonus {
2479 if profile.tool_name == bonus_tool {
2480 score *= bonus;
2481 } else {
2482 score /= bonus;
2484 }
2485 }
2486 if score > best_score {
2487 if best_score > 0.0 {
2488 second = Some((best_tool, best_score));
2489 }
2490 best_score = score;
2491 best_tool = profile.tool_name;
2492 } else if score > 0.0
2493 && profile.tool_name != best_tool
2494 && second.is_none_or(|(_, s)| score > s)
2495 {
2496 second = Some((profile.tool_name, score));
2497 }
2498 }
2499
2500 const MIN_THRESHOLD: f64 = 0.10;
2504 if best_score < MIN_THRESHOLD {
2505 let alternative = (best_score > 0.0).then_some((best_tool, best_score));
2506 return ("gnosis", 0.0, alternative);
2507 }
2508
2509 (
2510 best_tool,
2511 best_score,
2512 second.filter(|(tool, _)| *tool != best_tool),
2513 )
2514}
2515
2516#[cfg(test)]
2517fn profiled_tools() -> Vec<&'static str> {
2518 TOOL_PROFILES.iter().map(|p| p.tool_name).collect()
2519}
2520
2521#[cfg(test)]
2522fn profile_count() -> usize {
2523 TOOL_PROFILES.len()
2524}
2525
2526#[cfg(test)]
2527mod tests {
2528 use super::*;
2529 use std::collections::HashSet;
2530
2531 #[test]
2532 fn classify_empty_returns_gnosis() {
2533 let (tool, conf) = classify("");
2534 assert_eq!(tool, "gnosis");
2535 assert_eq!(conf, 0.0);
2536 }
2537
2538 #[test]
2539 fn classify_alternative_discloses_a_runner_up() {
2540 let (tool, confidence, alternative) =
2544 classify_with_alternative("recall beta quartz submarine design notes");
2545 assert!(confidence > 0.0, "expected a scored candidate: {tool}");
2546 if let Some((alt_tool, alt_confidence)) = alternative {
2547 assert_ne!(alt_tool, tool, "alternative must be a different tool");
2548 assert!(
2549 alt_confidence <= confidence,
2550 "alternative {alt_tool} ({alt_confidence}) beat {tool} ({confidence})"
2551 );
2552 }
2553 }
2554
2555 #[test]
2556 fn classify_unknown_offers_no_alternative() {
2557 let (tool, confidence, alternative) = classify_with_alternative("zzzqqx vvbnm");
2558 assert_eq!(tool, "gnosis");
2559 assert_eq!(confidence, 0.0);
2560 assert!(
2561 alternative.is_none(),
2562 "no candidate should surface for pure noise: {alternative:?}"
2563 );
2564 }
2565
2566 #[test]
2567 fn classify_whitespace_returns_gnosis() {
2568 let (tool, conf) = classify(" ");
2569 assert_eq!(tool, "gnosis");
2570 assert_eq!(conf, 0.0);
2571 }
2572
2573 #[test]
2574 fn classify_unknown_returns_gnosis() {
2575 let (tool, conf) = classify("xyzzy frobnicate");
2576 assert_eq!(tool, "gnosis");
2577 assert_eq!(conf, 0.0);
2578 }
2579
2580 #[test]
2581 fn classify_remember_routes_to_memory_create() {
2582 let (tool, _conf) = classify("remember that the sky is blue");
2583 assert_eq!(tool, "memory.create");
2584 }
2585
2586 #[test]
2587 fn classify_store_routes_to_memory_create() {
2588 let (tool, _conf) = classify("store this important fact");
2589 assert_eq!(tool, "memory.create");
2590 }
2591
2592 #[test]
2593 fn classify_recall_routes_to_memory_search() {
2594 let (tool, _conf) = classify("recall the last memory");
2597 assert_eq!(tool, "memory.search");
2598 }
2599
2600 #[test]
2601 fn classify_find_routes_to_memory_search() {
2602 let (tool, _conf) = classify("find BETA quartz submarine in memory");
2603 assert_eq!(tool, "memory.search");
2604 }
2605
2606 #[test]
2607 fn classify_what_do_you_remember_routes_to_memory_search() {
2608 let (tool, _conf) = classify("What do you remember about BETA quartz submarine?");
2609 assert_eq!(tool, "memory.search");
2610 }
2611
2612 #[test]
2613 fn classify_what_did_we_decide_routes_to_memory_search() {
2614 let (tool, _conf) = classify("What did we decide about BETA quartz submarine?");
2615 assert_eq!(tool, "memory.search");
2616 }
2617
2618 #[test]
2619 fn classify_look_up_routes_to_memory_search() {
2620 let (tool, _conf) = classify("look up the quartz submarine");
2621 assert_eq!(tool, "memory.search");
2622 }
2623
2624 #[test]
2625 fn classify_search_routes_to_memory_search() {
2626 let (tool, _conf) = classify("search for rust");
2627 assert_eq!(tool, "memory.search");
2628 }
2629
2630 #[test]
2631 fn classify_list_memories_routes_to_memory_list() {
2632 let (tool, _conf) = classify("list memories in codex");
2633 assert_eq!(tool, "memory.list");
2634 }
2635
2636 #[test]
2637 fn classify_delete_memory_routes_to_memory_delete() {
2638 let (tool, _conf) = classify("delete memory abc-123");
2639 assert_eq!(tool, "memory.delete");
2640 }
2641
2642 #[test]
2643 fn classify_karma_routes_to_karma_report() {
2644 let (tool, _conf) = classify("show me the karma report");
2645 assert_eq!(tool, "karma.report");
2646 }
2647
2648 #[test]
2649 fn classify_karma_history_routes_correctly() {
2650 let (tool, _conf) = classify("karma history");
2651 assert_eq!(tool, "karma.history");
2652 }
2653
2654 #[test]
2655 fn classify_dharma_status_routes_correctly() {
2656 let (tool, _conf) = classify("dharma status");
2657 assert_eq!(tool, "dharma.status");
2658 }
2659
2660 #[test]
2661 fn classify_dharma_rules_routes_correctly() {
2662 let (tool, _conf) = classify("show dharma rules");
2663 assert_eq!(tool, "dharma.rules");
2664 }
2665
2666 #[test]
2667 fn classify_harmony_routes_to_harmony_vector() {
2668 let (tool, _conf) = classify("harmony vector status");
2669 assert_eq!(tool, "harmony.vector");
2670 }
2671
2672 #[test]
2673 fn classify_gnosis_explain_routes_correctly() {
2674 let (tool, _conf) = classify("why was my action blocked");
2675 assert_eq!(tool, "gnosis.explain");
2676 }
2677
2678 #[test]
2679 fn classify_session_start_routes_correctly() {
2680 let (tool, _conf) = classify("start session research");
2681 assert_eq!(tool, "session.start");
2682 }
2683
2684 #[test]
2685 fn classify_session_end_routes_correctly() {
2686 let (tool, _conf) = classify("end session abc-123");
2687 assert_eq!(tool, "session.end");
2688 }
2689
2690 #[test]
2691 fn classify_session_continuity_routes_correctly() {
2692 for phrase in [
2694 "what did we decide last time",
2695 "resume where we left off",
2696 "where were we in the previous session",
2697 "continue from where I stopped",
2698 "pick up where we left off",
2699 ] {
2700 let (tool, conf) = classify(phrase);
2701 assert_eq!(tool, "session.continuity", "phrase: {phrase}");
2702 assert!(conf > 0.1, "phrase {phrase} confidence too low: {conf}");
2703 }
2704 }
2705
2706 #[test]
2707 fn classify_session_record_routes_correctly() {
2708 let (tool, _conf) = classify("record this decision for later");
2709 assert_eq!(tool, "session.record");
2710 }
2711
2712 #[test]
2713 fn classify_citta_status_routes_correctly() {
2714 let (tool, _conf) = classify("citta status");
2715 assert_eq!(tool, "citta.status");
2716 }
2717
2718 #[test]
2719 fn classify_dream_trigger_routes_correctly() {
2720 let (tool, _conf) = classify("trigger dream cycle");
2721 assert_eq!(tool, "dream.trigger");
2722 }
2723
2724 #[test]
2725 fn classify_consolidate_routes_correctly() {
2726 let (tool, _conf) = classify("consolidate duplicate memories");
2727 assert_eq!(tool, "memory.consolidate");
2728 }
2729
2730 #[test]
2731 fn classify_emergence_scan_routes_correctly() {
2732 let (tool, _conf) = classify("emergence scan for trending tags");
2733 assert_eq!(tool, "emergence.scan");
2734 }
2735
2736 #[test]
2737 fn classify_spiral_report_routes_correctly() {
2738 let (tool, _conf) = classify("spiral report for autonomy");
2739 assert_eq!(tool, "spiral.report");
2740 }
2741
2742 #[test]
2743 fn classify_retention_prune_routes_correctly() {
2744 let (tool, _conf) = classify("prune memories ready to forget");
2745 assert_eq!(tool, "retention.prune");
2746 }
2747
2748 #[test]
2749 fn classify_tools_list_routes_correctly() {
2750 let (tool, _conf) = classify("list tools");
2751 assert_eq!(tool, "tools.list");
2752 }
2753
2754 #[test]
2755 fn classify_system_health_routes_correctly() {
2756 let (tool, _conf) = classify("system health check");
2757 assert_eq!(tool, "system.health");
2758 }
2759
2760 #[test]
2761 fn classify_agent_register_routes_correctly() {
2762 let (tool, _conf) = classify("register agent worker-1");
2763 assert_eq!(tool, "agent.register");
2764 }
2765
2766 #[test]
2767 fn classify_task_distribute_routes_correctly() {
2768 let (tool, _conf) = classify("distribute task analyze data");
2769 assert_eq!(tool, "task.distribute");
2770 }
2771
2772 #[test]
2773 fn classify_nearby_memories_routes_correctly() {
2774 let (tool, _conf) = classify("memories nearby");
2777 assert_eq!(tool, "memory.nearby");
2778 }
2779
2780 #[test]
2781 fn classify_hybrid_recall_routes_correctly() {
2782 let (tool, _conf) = classify("hybrid recall for rust");
2783 assert_eq!(tool, "memory.hybrid_recall");
2784 }
2785
2786 #[test]
2787 fn classify_galaxy_stats_routes_correctly() {
2788 let (tool, _conf) = classify("galaxy stats overview");
2789 assert_eq!(tool, "galaxy.stats");
2790 }
2791
2792 #[test]
2793 fn classify_galaxy_export_routes_correctly() {
2794 let (tool, _conf) = classify("export galaxy backup");
2795 assert_eq!(tool, "galaxy.export");
2796 }
2797
2798 #[test]
2799 fn classify_kg_extract_routes_correctly() {
2800 let (tool, _conf) = classify("extract entities knowledge graph");
2801 assert_eq!(tool, "kg.extract");
2802 }
2803
2804 #[test]
2805 fn classify_kg_query_routes_correctly() {
2806 let (tool, _conf) = classify("knowledge graph query relationships");
2807 assert_eq!(tool, "kg.query");
2808 }
2809
2810 #[test]
2811 fn classify_kg_top_routes_correctly() {
2812 let (tool, _conf) = classify("top hub nodes knowledge graph");
2813 assert_eq!(tool, "kg.top");
2814 }
2815
2816 #[test]
2817 fn classify_graph_walk_routes_correctly() {
2818 let (tool, _conf) = classify("traverse graph walk bfs");
2819 assert_eq!(tool, "graph.walk");
2820 }
2821
2822 #[test]
2823 fn classify_graph_community_routes_correctly() {
2824 let (tool, _conf) = classify("detect communities clusters in graph");
2825 assert_eq!(tool, "graph.community");
2826 }
2827
2828 #[test]
2829 fn classify_graph_propagate_routes_correctly() {
2830 let (tool, _conf) = classify("propagate activation spread ripple");
2831 assert_eq!(tool, "graph.propagate");
2832 }
2833
2834 #[test]
2835 fn classify_galaxy_transfer_routes_correctly() {
2836 let (tool, _conf) = classify("transfer move memories galaxy");
2837 assert_eq!(tool, "galaxy.transfer");
2838 }
2839
2840 #[test]
2841 fn classify_galaxy_merge_routes_correctly() {
2842 let (tool, _conf) = classify("merge combine galaxies");
2843 assert_eq!(tool, "galaxy.merge");
2844 }
2845
2846 #[test]
2847 fn classify_galaxy_snapshot_routes_correctly() {
2848 let (tool, _conf) = classify("snapshot backup galaxy");
2849 assert_eq!(tool, "galaxy.snapshot");
2850 }
2851
2852 #[test]
2853 fn classify_galaxy_restore_routes_correctly() {
2854 let (tool, _conf) = classify("restore recover galaxy snapshot");
2855 assert_eq!(tool, "galaxy.restore");
2856 }
2857
2858 #[test]
2859 fn classify_agent_trust_routes_correctly() {
2860 let (tool, _conf) = classify("trust reliability agent score");
2861 assert_eq!(tool, "agent.trust");
2862 }
2863
2864 #[test]
2865 fn classify_agent_descriptions_routes_correctly() {
2866 let (tool, _conf) = classify("describe agent profile info");
2867 assert_eq!(tool, "agent.descriptions");
2868 }
2869
2870 #[test]
2871 fn classify_agent_capabilities_routes_correctly() {
2872 let (tool, _conf) = classify("agent capabilities skills abilities");
2873 assert_eq!(tool, "agent.capabilities");
2874 }
2875
2876 #[test]
2877 fn classify_agent_heartbeat_history_routes_correctly() {
2878 let (tool, _conf) = classify("heartbeat history log agent");
2879 assert_eq!(tool, "agent.heartbeat.history");
2880 }
2881
2882 #[test]
2883 fn classify_agent_deregister_routes_correctly() {
2884 let (tool, _conf) = classify("deregister unregister remove agent");
2885 assert_eq!(tool, "agent.deregister");
2886 }
2887
2888 #[test]
2889 fn classify_galaxy_dashboard_routes_correctly() {
2890 let (tool, _conf) = classify("galaxy dashboard overview panel");
2891 assert_eq!(tool, "galaxy.dashboard");
2892 }
2893
2894 #[test]
2895 fn classify_galaxy_backup_routes_correctly() {
2896 let (tool, _conf) = classify("backup archive galaxy dump");
2897 assert_eq!(tool, "galaxy.backup");
2898 }
2899
2900 #[test]
2901 fn classify_galaxy_taxonomy_routes_correctly() {
2902 let (tool, _conf) = classify("galaxy taxonomy classification categories");
2903 assert_eq!(tool, "galaxy.taxonomy");
2904 }
2905
2906 #[test]
2907 fn classify_galaxy_purge_routes_correctly() {
2908 let (tool, _conf) = classify("purge wipe clear galaxy");
2909 assert_eq!(tool, "galaxy.purge");
2910 }
2911
2912 #[test]
2913 fn classify_galaxy_health_routes_correctly() {
2914 let (tool, _conf) = classify("galaxy health diagnostic checkup");
2915 assert_eq!(tool, "galaxy.health");
2916 }
2917
2918 #[test]
2919 fn classify_memory_sort_routes_correctly() {
2920 let (tool, _conf) = classify("sort memories by importance");
2921 assert_eq!(tool, "memory.sort");
2922 }
2923
2924 #[test]
2925 fn classify_memory_filter_routes_correctly() {
2926 let (tool, _conf) = classify("filter memories by tag criteria");
2927 assert_eq!(tool, "memory.filter");
2928 }
2929
2930 #[test]
2931 fn classify_memory_deduplicate_routes_correctly() {
2932 let (tool, _conf) = classify("deduplicate memories redundant duplicate");
2933 assert_eq!(tool, "memory.deduplicate");
2934 }
2935
2936 #[test]
2937 fn classify_memory_export_routes_correctly() {
2938 let (tool, _conf) = classify("export memories csv format download");
2939 assert_eq!(tool, "memory.export");
2940 }
2941
2942 #[test]
2943 fn classify_homeostasis_check_routes_correctly() {
2944 let (tool, _conf) = classify("homeostasis check balance vitals metrics");
2945 assert_eq!(tool, "homeostasis.check");
2946 }
2947
2948 #[test]
2949 fn classify_homeostasis_adjust_routes_correctly() {
2950 let (tool, _conf) = classify("homeostasis adjust rebalance weight tune");
2951 assert_eq!(tool, "homeostasis.adjust");
2952 }
2953
2954 #[test]
2955 fn classify_homeostasis_history_routes_correctly() {
2956 let (tool, _conf) = classify("homeostasis history trend past samples");
2957 assert_eq!(tool, "homeostasis.history");
2958 }
2959
2960 #[test]
2961 fn classify_homeostasis_alerts_routes_correctly() {
2962 let (tool, _conf) = classify("homeostasis alerts warning critical threshold");
2963 assert_eq!(tool, "homeostasis.alerts");
2964 }
2965
2966 #[test]
2967 fn classify_reflex_dispatch_routes_correctly() {
2968 let (tool, _conf) = classify("dispatch reflex e_stop emergency handler");
2969 assert_eq!(tool, "reflex.dispatch");
2970 }
2971
2972 #[test]
2973 fn classify_reflex_status_routes_correctly() {
2974 let (tool, _conf) = classify("reflex status table registered handlers");
2975 assert_eq!(tool, "reflex.status");
2976 }
2977
2978 #[test]
2979 fn classify_workspace_spotlight_routes_correctly() {
2980 let (tool, _conf) = classify("workspace spotlight attention arbitration");
2981 assert_eq!(tool, "workspace.spotlight");
2982 }
2983
2984 #[test]
2985 fn classify_workspace_events_routes_correctly() {
2986 let (tool, _conf) = classify("workspace recent events backlog history");
2987 assert_eq!(tool, "workspace.events");
2988 }
2989
2990 #[test]
2991 fn classify_workspace_publish_routes_correctly() {
2992 let (tool, _conf) = classify("publish broadcast workspace event emit");
2993 assert_eq!(tool, "workspace.publish");
2994 }
2995
2996 #[test]
2997 fn classify_workspace_stats_routes_correctly() {
2998 let (tool, _conf) = classify("workspace stats statistics transfers count");
2999 assert_eq!(tool, "workspace.stats");
3000 }
3001
3002 #[test]
3003 fn classify_timescale_status_routes_correctly() {
3004 let (tool, _conf) = classify("timescale status tier bus brain_wave active");
3005 assert_eq!(tool, "timescale.status");
3006 }
3007
3008 #[test]
3009 fn classify_timescale_hooks_routes_correctly() {
3010 let (tool, _conf) = classify("timescale hooks list tick timeout performance");
3011 assert_eq!(tool, "timescale.hooks");
3012 }
3013
3014 #[test]
3015 fn classify_confidence_is_reasonable() {
3016 let (_tool, conf) = classify("remember that rust is fast");
3017 assert!(
3018 conf > 0.15,
3019 "confidence should be > 0.15 for clear match, got {conf}"
3020 );
3021 }
3022
3023 #[test]
3024 fn classify_case_insensitive() {
3025 let (tool1, _) = classify("REMEMBER THAT");
3026 let (tool2, _) = classify("remember that");
3027 assert_eq!(tool1, tool2);
3028 }
3029
3030 #[test]
3031 fn classify_partial_match_works() {
3032 let (tool, conf) = classify("search rust");
3033 assert_eq!(tool, "memory.search");
3034 assert!(conf > 0.0);
3035 }
3036
3037 #[test]
3038 fn classify_multi_word_query() {
3039 let (tool, _conf) = classify("show me the effectiveness report for tools");
3040 assert_eq!(tool, "tools.effectiveness_report");
3041 }
3042
3043 #[test]
3044 fn profile_count_is_reasonable() {
3045 assert!(
3047 profile_count() >= 60,
3048 "expected 60+ profiles, got {}",
3049 profile_count()
3050 );
3051 }
3052
3053 #[test]
3054 fn profiled_tools_are_unique() {
3055 let tools = profiled_tools();
3056 let set: HashSet<&str> = tools.iter().copied().collect();
3057 assert_eq!(tools.len(), set.len(), "duplicate tool names in profiles");
3058 }
3059
3060 #[test]
3061 fn classify_unique_patterns_count() {
3062 let inputs = [
3063 "remember",
3064 "recall",
3065 "list memories",
3066 "delete memory",
3067 "search",
3068 "query",
3069 "associate",
3070 "associations",
3071 "consolidate",
3072 "decay",
3073 "batch read",
3074 "update memory",
3075 "tag memory",
3076 "memory stats",
3077 "hybrid recall",
3078 "count memories",
3079 "list tags",
3080 "mine associations",
3081 "start session",
3082 "checkpoint",
3083 "recall session",
3084 "end session",
3085 "list sessions",
3086 "citta status",
3087 "reflect",
3088 "coherence",
3089 "dream status",
3090 "trigger dream",
3091 "effectiveness",
3092 "retire tool",
3093 "pattern search",
3094 "salience",
3095 "serendipity",
3096 "detect clusters",
3097 "list constellations",
3098 "galaxy stats",
3099 "export galaxy",
3100 "import galaxy",
3101 "karma",
3102 "karma history",
3103 "clear karma",
3104 "dharma rules",
3105 "dharma audit",
3106 "dharma profiles",
3107 "dharma",
3108 "register agent",
3109 "list agents",
3110 "heartbeat",
3111 "distribute task",
3112 "task status",
3113 "system health",
3114 "system config",
3115 "flush",
3116 "tools",
3117 "nearby memories",
3118 "vector search",
3119 "find similar",
3120 "extract entities knowledge graph",
3121 "knowledge graph query",
3122 "top hub nodes",
3123 "traverse graph walk",
3124 "detect communities",
3125 "propagate activation",
3126 "transfer galaxy",
3127 "merge galaxies",
3128 "snapshot galaxy",
3129 "restore galaxy",
3130 "sort memories",
3131 "filter memories",
3132 "deduplicate memories",
3133 "export memories csv",
3134 "homeostasis check",
3135 "homeostasis adjust",
3136 "homeostasis history",
3137 "homeostasis alerts",
3138 "dispatch reflex e_stop",
3139 "reflex status table",
3140 "workspace spotlight attention",
3141 "workspace recent events",
3142 "publish workspace event",
3143 "workspace stats summary",
3144 "timescale status tiers",
3145 "timescale hooks tick",
3146 ];
3147 let mut tools: HashSet<&str> = HashSet::new();
3148 for input in &inputs {
3149 let (tool, _) = classify(input);
3150 tools.insert(tool);
3151 }
3152 assert!(
3153 tools.len() >= 30,
3154 "Expected 30+ unique NLU targets, got {}",
3155 tools.len()
3156 );
3157 }
3158
3159 #[test]
3160 fn classify_vector_search_routes_correctly() {
3161 let (tool, conf) = classify("vector search similar memories");
3162 assert_eq!(tool, "memory.vector.search");
3163 assert!(conf > 0.0);
3164 }
3165
3166 #[test]
3167 fn classify_embedding_search_routes_correctly() {
3168 let (tool, conf) = classify("embedding similarity lookup");
3169 assert_eq!(tool, "memory.vector.search");
3170 assert!(conf > 0.0);
3171 }
3172
3173 #[test]
3174 fn classify_semantic_search_routes_correctly() {
3175 let (tool, conf) = classify("semantic similarity search");
3176 assert_eq!(tool, "memory.vector.search");
3177 assert!(conf > 0.0);
3178 }
3179
3180 #[test]
3181 fn classify_stemming_handles_morphological_variants() {
3182 let (tool1, _) = classify("searching for rust");
3184 let (tool2, _) = classify("search for rust");
3185 assert_eq!(tool1, tool2);
3186
3187 let (tool3, _) = classify("stored important fact");
3189 let (tool4, _) = classify("store important fact");
3190 assert_eq!(tool3, tool4);
3191
3192 let (tool5, _) = classify("list memories");
3194 let (tool6, _) = classify("list memory");
3195 assert_eq!(tool5, tool6);
3196 }
3197
3198 #[test]
3199 fn stem_handles_unicode_without_panicking() {
3200 assert_eq!(stem("xéing"), "xé");
3203 assert_eq!(stem("éing"), "é");
3204 assert_eq!(stem("caféing"), "café");
3205 assert_eq!(stem("running"), "run");
3207 assert_eq!(stem("swimming"), "swim");
3208 assert_eq!(stem("searching"), "search");
3209 assert_eq!(stem("typing"), "typ");
3210 assert_eq!(stem("memories"), "memory");
3211 assert_eq!(stem("stored"), "store");
3212 }
3213
3214 #[test]
3215 fn classify_handles_unicode_thoughts_without_panicking() {
3216 let (tool, _conf) = classify("caféing sur les mémoires");
3218 assert!(!tool.is_empty());
3219 let (tool2, _conf2) = classify("mémoire éing recherche");
3220 assert!(!tool2.is_empty());
3221 }
3222
3223 #[test]
3224 fn classify_confidence_improved_with_stopwords() {
3225 let (_, conf) = classify("remember that rust is fast");
3227 assert!(
3228 conf > 0.20,
3229 "confidence should be > 0.20 with stopword filtering, got {conf}"
3230 );
3231 }
3232
3233 #[test]
3236 fn classify_forecast_routes_to_selfmodel_forecast() {
3237 let (tool, _conf) = classify("forecast cpu load for next 5 samples");
3238 assert_eq!(tool, "selfmodel.forecast");
3239 }
3240
3241 #[test]
3242 fn classify_predict_routes_to_selfmodel_forecast() {
3243 let (tool, _conf) = classify("predict memory pressure trend");
3244 assert_eq!(tool, "selfmodel.forecast");
3245 }
3246
3247 #[test]
3248 fn classify_alerts_routes_to_selfmodel_alerts() {
3249 let (tool, _conf) = classify("selfmodel alerts");
3250 assert_eq!(tool, "selfmodel.alerts");
3251 }
3252
3253 #[test]
3254 fn classify_warning_routes_to_selfmodel_alerts() {
3255 let (tool, _conf) = classify("selfmodel critical warnings");
3256 assert_eq!(tool, "selfmodel.alerts");
3257 }
3258
3259 #[test]
3260 fn classify_snapshot_routes_to_selfmodel_snapshot() {
3261 let (tool, _conf) = classify("selfmodel snapshot");
3262 assert_eq!(tool, "selfmodel.snapshot");
3263 }
3264
3265 #[test]
3266 fn classify_introspection_routes_to_selfmodel_snapshot() {
3267 let (tool, _conf) = classify("show introspection state overview");
3268 assert_eq!(tool, "selfmodel.snapshot");
3269 }
3270
3271 #[test]
3274 fn classify_bicameral_debate_routes_to_bicameral_reason() {
3275 let (tool, _conf) = classify("bicameral debate on rust vs python");
3276 assert_eq!(tool, "bicameral.reason");
3277 }
3278
3279 #[test]
3280 fn classify_hemisphere_consensus_routes_to_bicameral_reason() {
3281 let (tool, _conf) = classify("dual hemisphere consensus deliberation");
3282 assert_eq!(tool, "bicameral.reason");
3283 }
3284
3285 #[test]
3286 fn classify_bicameral_status_routes_correctly() {
3287 let (tool, _conf) = classify("bicameral hemisphere status");
3288 assert_eq!(tool, "bicameral.status");
3289 }
3290
3291 #[test]
3292 fn classify_callosum_routes_to_bicameral_reason() {
3293 let (tool, _conf) = classify("corpus callosum debate perspectives");
3294 assert_eq!(tool, "bicameral.reason");
3295 }
3296
3297 #[test]
3300 fn classify_drive_snapshot_routes_correctly() {
3301 let (tool, _conf) = classify("drive snapshot current motivation state");
3302 assert_eq!(tool, "drive.snapshot");
3303 }
3304
3305 #[test]
3306 fn classify_emotion_routes_to_drive_snapshot() {
3307 let (tool, _conf) = classify("show current emotion and mood");
3308 assert_eq!(tool, "drive.snapshot");
3309 }
3310
3311 #[test]
3312 fn classify_drive_event_routes_correctly() {
3313 let (tool, _conf) = classify("inject drive event reward for success");
3314 assert_eq!(tool, "drive.event");
3315 }
3316
3317 #[test]
3318 fn classify_curiosity_routes_to_drive_snapshot() {
3319 let (tool, _conf) = classify("curiosity satisfaction caution levels");
3320 assert_eq!(tool, "drive.snapshot");
3321 }
3322
3323 #[test]
3326 fn adversarial_remember_in_redteam_query_doesnt_misroute() {
3327 let (tool, _conf) = classify("redteam scan to remember uncovered vectors");
3329 assert_ne!(
3330 tool, "memory.create",
3331 "redteam query should not route to memory.create even with 'remember' embedded"
3332 );
3333 }
3334
3335 #[test]
3336 fn adversarial_delete_in_search_query_doesnt_misroute() {
3337 let (tool, _conf) = classify("search for memories about delete operations");
3339 assert_ne!(
3340 tool, "memory.delete",
3341 "search query should not route to memory.delete even with 'delete' embedded"
3342 );
3343 }
3344
3345 #[test]
3346 fn adversarial_store_in_gnosis_query_doesnt_misroute() {
3347 let (tool, _conf) = classify("explain why the store blocked my action");
3349 assert_ne!(
3350 tool, "memory.create",
3351 "gnosis query should not route to memory.create even with 'store' embedded"
3352 );
3353 }
3354
3355 #[test]
3356 fn adversarial_repeated_keyword_doesnt_inflate_score() {
3357 let (tool, conf) = classify("remember remember remember remember remember remember");
3359 assert_eq!(tool, "memory.create");
3360 assert!(
3362 conf <= 1.0,
3363 "repeated keywords should not inflate confidence beyond 1.0: got {conf}"
3364 );
3365 }
3366
3367 #[test]
3368 fn adversarial_keyword_stuffing_doesnt_misroute() {
3369 let (tool, _conf) = classify("remember delete search list recall store");
3371 assert!(
3373 tool.starts_with("memory."),
3374 "keyword stuffing should still route to a memory tool, got {tool}"
3375 );
3376 }
3377
3378 #[test]
3379 fn adversarial_redteam_with_memory_keyword_doesnt_misroute() {
3380 let (tool, _conf) = classify("redteam proposals for memory poisoning attack");
3382 assert_eq!(
3383 tool, "redteam.proposals",
3384 "redteam query should route to redteam.proposals even with 'memory' embedded"
3385 );
3386 }
3387
3388 #[test]
3389 fn adversarial_friction_with_delete_keyword_doesnt_misroute() {
3390 let (tool, _conf) = classify("log friction about delete operations failing");
3392 assert_ne!(
3394 tool, "memory.delete",
3395 "friction query should not route to memory.delete even with 'delete' embedded"
3396 );
3397 }
3398
3399 #[test]
3400 fn adversarial_long_input_doesnt_cascade_misroute() {
3401 let input = "remember to search for delete and list and recall and store and save \
3403 and memorize and retrieve and fetch and get and load and access and \
3404 query and find and look and check and count and purge and forget \
3405 and remove and drop and clear and wipe and erase and destroy";
3406 let (tool, _conf) = classify(input);
3407 assert!(
3409 tool.starts_with("memory.") || tool == "gnosis",
3410 "long input should route to memory tool or gnosis, got {tool}"
3411 );
3412 }
3413
3414 #[test]
3415 fn adversarial_empty_words_between_keywords() {
3416 let (tool1, _) = classify("remember the important fact");
3418 let (tool2, _) = classify("remember the important fact");
3419 assert_eq!(tool1, tool2, "extra whitespace should not change routing");
3420 }
3421
3422 #[test]
3423 fn adversarial_unicode_homoglyph_doesnt_misroute() {
3424 let (tool, _conf) = classify("rеmеmbеr this fact"); assert_ne!(
3429 tool, "memory.create",
3430 "unicode homoglyphs should not trick the router into memory.create"
3431 );
3432 }
3433
3434 #[test]
3437 fn classify_imagine_scenarios_routes_to_imagine_scenario() {
3438 let (tool, _conf) = classify("imagine scenarios for improving performance");
3439 assert_eq!(tool, "imagine.scenario");
3440 }
3441
3442 #[test]
3443 fn classify_brainstorm_routes_to_imagine_scenario() {
3444 let (tool, _conf) = classify("brainstorm contingency plans for deployment");
3445 assert_eq!(tool, "imagine.scenario");
3446 }
3447
3448 #[test]
3449 fn classify_envision_routes_to_imagine_scenario() {
3450 let (tool, _conf) = classify("envision what-if possibilities for the system");
3451 assert_eq!(tool, "imagine.scenario");
3452 }
3453
3454 #[test]
3455 fn classify_reflect_routes_to_imagine_reflect() {
3456 let (tool, _conf) =
3457 classify("counterfactual reflect on what should have been done instead");
3458 assert_eq!(tool, "imagine.reflect");
3459 }
3460
3461 #[test]
3462 fn classify_counterfactual_routes_to_imagine_reflect() {
3463 let (tool, _conf) = classify("counterfactual analysis of the decision");
3464 assert_eq!(tool, "imagine.reflect");
3465 }
3466
3467 use proptest::prelude::*;
3470
3471 proptest! {
3472 #[test]
3474 fn classify_never_panics(text in ".*") {
3475 let (tool, conf) = classify(&text);
3476 prop_assert!(!tool.is_empty(), "tool name must be non-empty");
3477 prop_assert!(
3478 (0.0..=1.0).contains(&conf),
3479 "confidence must be in [0,1], got {conf}"
3480 );
3481 }
3482
3483 #[test]
3485 fn classify_never_panics_bytes(data in proptest::collection::vec(any::<u8>(), 0..256)) {
3486 let text = String::from_utf8_lossy(&data);
3487 let (tool, conf) = classify(&text);
3488 prop_assert!(!tool.is_empty());
3489 prop_assert!((0.0..=1.0).contains(&conf));
3490 }
3491
3492 #[test]
3494 fn classify_is_deterministic(text in ".*") {
3495 let (tool1, conf1) = classify(&text);
3496 let (tool2, conf2) = classify(&text);
3497 prop_assert_eq!(tool1, tool2);
3498 prop_assert!((conf1 - conf2).abs() < f64::EPSILON);
3499 }
3500
3501 #[test]
3503 fn classify_empty_returns_gnosis_prop(ws in r"[ \t\n\r]*") {
3504 let (tool, conf) = classify(&ws);
3505 prop_assert_eq!(tool, "gnosis");
3506 prop_assert_eq!(conf, 0.0);
3507 }
3508
3509 #[test]
3511 fn classify_confidence_is_finite(text in ".*") {
3512 let (_, conf) = classify(&text);
3513 prop_assert!(conf.is_finite(), "confidence must be finite, got {conf}");
3514 }
3515 }
3516}