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 probe = lower.trim_start();
2455 if let Some((_, tool, _)) = PHRASE_ROUTES
2456 .iter()
2457 .find(|(phrase, _, _)| probe.starts_with(phrase))
2458 {
2459 return (tool, 1.0, None);
2460 }
2461
2462 let tokens = tokenize(&lower);
2463 if tokens.is_empty() {
2464 return ("gnosis", 0.0, None);
2465 }
2466
2467 let input_tf = term_frequencies(&tokens);
2468
2469 let first_word = probe.split_whitespace().next().unwrap_or("");
2471 let prefix_bonus: Option<(&str, f64)> = PREFIX_ROUTES
2472 .iter()
2473 .find(|(verb, _, _)| *verb == first_word)
2474 .map(|(_, tool, bonus)| (*tool, *bonus));
2475
2476 let mut best_tool = "gnosis";
2477 let mut best_score = 0.0;
2478 let mut second: Option<(&'static str, f64)> = None;
2479
2480 for profile in TOOL_PROFILES {
2481 let mut score = cosine_similarity(&input_tf, profile);
2482 if let Some((bonus_tool, bonus)) = prefix_bonus {
2484 if profile.tool_name == bonus_tool {
2485 score *= bonus;
2486 } else {
2487 score /= bonus;
2489 }
2490 }
2491 if score > best_score {
2492 if best_score > 0.0 {
2493 second = Some((best_tool, best_score));
2494 }
2495 best_score = score;
2496 best_tool = profile.tool_name;
2497 } else if score > 0.0
2498 && profile.tool_name != best_tool
2499 && second.is_none_or(|(_, s)| score > s)
2500 {
2501 second = Some((profile.tool_name, score));
2502 }
2503 }
2504
2505 const MIN_THRESHOLD: f64 = 0.10;
2509 if best_score < MIN_THRESHOLD {
2510 let alternative = (best_score > 0.0).then_some((best_tool, best_score));
2511 return ("gnosis", 0.0, alternative);
2512 }
2513
2514 (
2515 best_tool,
2516 best_score,
2517 second.filter(|(tool, _)| *tool != best_tool),
2518 )
2519}
2520
2521#[cfg(test)]
2522fn profiled_tools() -> Vec<&'static str> {
2523 TOOL_PROFILES.iter().map(|p| p.tool_name).collect()
2524}
2525
2526#[cfg(test)]
2527fn profile_count() -> usize {
2528 TOOL_PROFILES.len()
2529}
2530
2531#[cfg(test)]
2532mod tests {
2533 use super::*;
2534 use std::collections::HashSet;
2535
2536 #[test]
2537 fn classify_empty_returns_gnosis() {
2538 let (tool, conf) = classify("");
2539 assert_eq!(tool, "gnosis");
2540 assert_eq!(conf, 0.0);
2541 }
2542
2543 #[test]
2544 fn classify_alternative_discloses_a_runner_up() {
2545 let (tool, confidence, alternative) =
2549 classify_with_alternative("recall beta quartz submarine design notes");
2550 assert!(confidence > 0.0, "expected a scored candidate: {tool}");
2551 if let Some((alt_tool, alt_confidence)) = alternative {
2552 assert_ne!(alt_tool, tool, "alternative must be a different tool");
2553 assert!(
2554 alt_confidence <= confidence,
2555 "alternative {alt_tool} ({alt_confidence}) beat {tool} ({confidence})"
2556 );
2557 }
2558 }
2559
2560 #[test]
2561 fn classify_unknown_offers_no_alternative() {
2562 let (tool, confidence, alternative) = classify_with_alternative("zzzqqx vvbnm");
2563 assert_eq!(tool, "gnosis");
2564 assert_eq!(confidence, 0.0);
2565 assert!(
2566 alternative.is_none(),
2567 "no candidate should surface for pure noise: {alternative:?}"
2568 );
2569 }
2570
2571 #[test]
2572 fn classify_whitespace_returns_gnosis() {
2573 let (tool, conf) = classify(" ");
2574 assert_eq!(tool, "gnosis");
2575 assert_eq!(conf, 0.0);
2576 }
2577
2578 #[test]
2579 fn classify_unknown_returns_gnosis() {
2580 let (tool, conf) = classify("xyzzy frobnicate");
2581 assert_eq!(tool, "gnosis");
2582 assert_eq!(conf, 0.0);
2583 }
2584
2585 #[test]
2586 fn classify_remember_routes_to_memory_create() {
2587 let (tool, _conf) = classify("remember that the sky is blue");
2588 assert_eq!(tool, "memory.create");
2589 }
2590
2591 #[test]
2592 fn classify_store_routes_to_memory_create() {
2593 let (tool, _conf) = classify("store this important fact");
2594 assert_eq!(tool, "memory.create");
2595 }
2596
2597 #[test]
2598 fn classify_recall_routes_to_memory_search() {
2599 let (tool, _conf) = classify("recall the last memory");
2602 assert_eq!(tool, "memory.search");
2603 }
2604
2605 #[test]
2606 fn classify_find_routes_to_memory_search() {
2607 let (tool, _conf) = classify("find BETA quartz submarine in memory");
2608 assert_eq!(tool, "memory.search");
2609 }
2610
2611 #[test]
2612 fn classify_what_do_you_remember_routes_to_memory_search() {
2613 let (tool, _conf) = classify("What do you remember about BETA quartz submarine?");
2614 assert_eq!(tool, "memory.search");
2615 }
2616
2617 #[test]
2618 fn classify_what_did_we_decide_routes_to_memory_search() {
2619 let (tool, _conf) = classify("What did we decide about BETA quartz submarine?");
2620 assert_eq!(tool, "memory.search");
2621 }
2622
2623 #[test]
2624 fn classify_look_up_routes_to_memory_search() {
2625 let (tool, _conf) = classify("look up the quartz submarine");
2626 assert_eq!(tool, "memory.search");
2627 }
2628
2629 #[test]
2630 fn classify_search_routes_to_memory_search() {
2631 let (tool, _conf) = classify("search for rust");
2632 assert_eq!(tool, "memory.search");
2633 }
2634
2635 #[test]
2636 fn classify_list_memories_routes_to_memory_list() {
2637 let (tool, _conf) = classify("list memories in codex");
2638 assert_eq!(tool, "memory.list");
2639 }
2640
2641 #[test]
2642 fn classify_delete_memory_routes_to_memory_delete() {
2643 let (tool, _conf) = classify("delete memory abc-123");
2644 assert_eq!(tool, "memory.delete");
2645 }
2646
2647 #[test]
2648 fn classify_karma_routes_to_karma_report() {
2649 let (tool, _conf) = classify("show me the karma report");
2650 assert_eq!(tool, "karma.report");
2651 }
2652
2653 #[test]
2654 fn classify_karma_history_routes_correctly() {
2655 let (tool, _conf) = classify("karma history");
2656 assert_eq!(tool, "karma.history");
2657 }
2658
2659 #[test]
2660 fn classify_dharma_status_routes_correctly() {
2661 let (tool, _conf) = classify("dharma status");
2662 assert_eq!(tool, "dharma.status");
2663 }
2664
2665 #[test]
2666 fn classify_dharma_rules_routes_correctly() {
2667 let (tool, _conf) = classify("show dharma rules");
2668 assert_eq!(tool, "dharma.rules");
2669 }
2670
2671 #[test]
2672 fn classify_harmony_routes_to_harmony_vector() {
2673 let (tool, _conf) = classify("harmony vector status");
2674 assert_eq!(tool, "harmony.vector");
2675 }
2676
2677 #[test]
2678 fn classify_gnosis_explain_routes_correctly() {
2679 let (tool, _conf) = classify("why was my action blocked");
2680 assert_eq!(tool, "gnosis.explain");
2681 }
2682
2683 #[test]
2684 fn classify_session_start_routes_correctly() {
2685 let (tool, _conf) = classify("start session research");
2686 assert_eq!(tool, "session.start");
2687 }
2688
2689 #[test]
2690 fn classify_session_end_routes_correctly() {
2691 let (tool, _conf) = classify("end session abc-123");
2692 assert_eq!(tool, "session.end");
2693 }
2694
2695 #[test]
2696 fn classify_session_continuity_routes_correctly() {
2697 for phrase in [
2699 "what did we decide last time",
2700 "resume where we left off",
2701 "where were we in the previous session",
2702 "continue from where I stopped",
2703 "pick up where we left off",
2704 ] {
2705 let (tool, conf) = classify(phrase);
2706 assert_eq!(tool, "session.continuity", "phrase: {phrase}");
2707 assert!(conf > 0.1, "phrase {phrase} confidence too low: {conf}");
2708 }
2709 }
2710
2711 #[test]
2712 fn classify_bare_where_were_we_routes_to_continuity() {
2713 let (tool, conf) = classify("where were we");
2716 assert_eq!(tool, "session.continuity");
2717 assert_eq!(conf, 1.0);
2718 let (tool, conf) = classify("Where were we?");
2719 assert_eq!(tool, "session.continuity");
2720 assert_eq!(conf, 1.0);
2721 }
2722
2723 #[test]
2724 fn classify_every_advertised_phrase_bare_and_with_suffix() {
2725 for (phrase, tool, _) in PHRASE_ROUTES {
2729 let (bare_tool, bare_conf) = classify(phrase);
2730 assert_eq!(&bare_tool, tool, "bare phrase {phrase:?}");
2731 assert_eq!(bare_conf, 1.0, "bare phrase {phrase:?} confidence");
2732 let suffixed = format!("{phrase} tomorrow please");
2733 let (suffixed_tool, suffixed_conf) = classify(&suffixed);
2734 assert_eq!(&suffixed_tool, tool, "suffixed phrase {suffixed:?}");
2735 assert_eq!(
2736 suffixed_conf, 1.0,
2737 "suffixed phrase {suffixed:?} confidence"
2738 );
2739 }
2740 }
2741
2742 #[test]
2743 fn classify_session_record_routes_correctly() {
2744 let (tool, _conf) = classify("record this decision for later");
2745 assert_eq!(tool, "session.record");
2746 }
2747
2748 #[test]
2749 fn classify_citta_status_routes_correctly() {
2750 let (tool, _conf) = classify("citta status");
2751 assert_eq!(tool, "citta.status");
2752 }
2753
2754 #[test]
2755 fn classify_dream_trigger_routes_correctly() {
2756 let (tool, _conf) = classify("trigger dream cycle");
2757 assert_eq!(tool, "dream.trigger");
2758 }
2759
2760 #[test]
2761 fn classify_consolidate_routes_correctly() {
2762 let (tool, _conf) = classify("consolidate duplicate memories");
2763 assert_eq!(tool, "memory.consolidate");
2764 }
2765
2766 #[test]
2767 fn classify_emergence_scan_routes_correctly() {
2768 let (tool, _conf) = classify("emergence scan for trending tags");
2769 assert_eq!(tool, "emergence.scan");
2770 }
2771
2772 #[test]
2773 fn classify_spiral_report_routes_correctly() {
2774 let (tool, _conf) = classify("spiral report for autonomy");
2775 assert_eq!(tool, "spiral.report");
2776 }
2777
2778 #[test]
2779 fn classify_retention_prune_routes_correctly() {
2780 let (tool, _conf) = classify("prune memories ready to forget");
2781 assert_eq!(tool, "retention.prune");
2782 }
2783
2784 #[test]
2785 fn classify_tools_list_routes_correctly() {
2786 let (tool, _conf) = classify("list tools");
2787 assert_eq!(tool, "tools.list");
2788 }
2789
2790 #[test]
2791 fn classify_system_health_routes_correctly() {
2792 let (tool, _conf) = classify("system health check");
2793 assert_eq!(tool, "system.health");
2794 }
2795
2796 #[test]
2797 fn classify_agent_register_routes_correctly() {
2798 let (tool, _conf) = classify("register agent worker-1");
2799 assert_eq!(tool, "agent.register");
2800 }
2801
2802 #[test]
2803 fn classify_task_distribute_routes_correctly() {
2804 let (tool, _conf) = classify("distribute task analyze data");
2805 assert_eq!(tool, "task.distribute");
2806 }
2807
2808 #[test]
2809 fn classify_nearby_memories_routes_correctly() {
2810 let (tool, _conf) = classify("memories nearby");
2813 assert_eq!(tool, "memory.nearby");
2814 }
2815
2816 #[test]
2817 fn classify_hybrid_recall_routes_correctly() {
2818 let (tool, _conf) = classify("hybrid recall for rust");
2819 assert_eq!(tool, "memory.hybrid_recall");
2820 }
2821
2822 #[test]
2823 fn classify_galaxy_stats_routes_correctly() {
2824 let (tool, _conf) = classify("galaxy stats overview");
2825 assert_eq!(tool, "galaxy.stats");
2826 }
2827
2828 #[test]
2829 fn classify_galaxy_export_routes_correctly() {
2830 let (tool, _conf) = classify("export galaxy backup");
2831 assert_eq!(tool, "galaxy.export");
2832 }
2833
2834 #[test]
2835 fn classify_kg_extract_routes_correctly() {
2836 let (tool, _conf) = classify("extract entities knowledge graph");
2837 assert_eq!(tool, "kg.extract");
2838 }
2839
2840 #[test]
2841 fn classify_kg_query_routes_correctly() {
2842 let (tool, _conf) = classify("knowledge graph query relationships");
2843 assert_eq!(tool, "kg.query");
2844 }
2845
2846 #[test]
2847 fn classify_kg_top_routes_correctly() {
2848 let (tool, _conf) = classify("top hub nodes knowledge graph");
2849 assert_eq!(tool, "kg.top");
2850 }
2851
2852 #[test]
2853 fn classify_graph_walk_routes_correctly() {
2854 let (tool, _conf) = classify("traverse graph walk bfs");
2855 assert_eq!(tool, "graph.walk");
2856 }
2857
2858 #[test]
2859 fn classify_graph_community_routes_correctly() {
2860 let (tool, _conf) = classify("detect communities clusters in graph");
2861 assert_eq!(tool, "graph.community");
2862 }
2863
2864 #[test]
2865 fn classify_graph_propagate_routes_correctly() {
2866 let (tool, _conf) = classify("propagate activation spread ripple");
2867 assert_eq!(tool, "graph.propagate");
2868 }
2869
2870 #[test]
2871 fn classify_galaxy_transfer_routes_correctly() {
2872 let (tool, _conf) = classify("transfer move memories galaxy");
2873 assert_eq!(tool, "galaxy.transfer");
2874 }
2875
2876 #[test]
2877 fn classify_galaxy_merge_routes_correctly() {
2878 let (tool, _conf) = classify("merge combine galaxies");
2879 assert_eq!(tool, "galaxy.merge");
2880 }
2881
2882 #[test]
2883 fn classify_galaxy_snapshot_routes_correctly() {
2884 let (tool, _conf) = classify("snapshot backup galaxy");
2885 assert_eq!(tool, "galaxy.snapshot");
2886 }
2887
2888 #[test]
2889 fn classify_galaxy_restore_routes_correctly() {
2890 let (tool, _conf) = classify("restore recover galaxy snapshot");
2891 assert_eq!(tool, "galaxy.restore");
2892 }
2893
2894 #[test]
2895 fn classify_agent_trust_routes_correctly() {
2896 let (tool, _conf) = classify("trust reliability agent score");
2897 assert_eq!(tool, "agent.trust");
2898 }
2899
2900 #[test]
2901 fn classify_agent_descriptions_routes_correctly() {
2902 let (tool, _conf) = classify("describe agent profile info");
2903 assert_eq!(tool, "agent.descriptions");
2904 }
2905
2906 #[test]
2907 fn classify_agent_capabilities_routes_correctly() {
2908 let (tool, _conf) = classify("agent capabilities skills abilities");
2909 assert_eq!(tool, "agent.capabilities");
2910 }
2911
2912 #[test]
2913 fn classify_agent_heartbeat_history_routes_correctly() {
2914 let (tool, _conf) = classify("heartbeat history log agent");
2915 assert_eq!(tool, "agent.heartbeat.history");
2916 }
2917
2918 #[test]
2919 fn classify_agent_deregister_routes_correctly() {
2920 let (tool, _conf) = classify("deregister unregister remove agent");
2921 assert_eq!(tool, "agent.deregister");
2922 }
2923
2924 #[test]
2925 fn classify_galaxy_dashboard_routes_correctly() {
2926 let (tool, _conf) = classify("galaxy dashboard overview panel");
2927 assert_eq!(tool, "galaxy.dashboard");
2928 }
2929
2930 #[test]
2931 fn classify_galaxy_backup_routes_correctly() {
2932 let (tool, _conf) = classify("backup archive galaxy dump");
2933 assert_eq!(tool, "galaxy.backup");
2934 }
2935
2936 #[test]
2937 fn classify_galaxy_taxonomy_routes_correctly() {
2938 let (tool, _conf) = classify("galaxy taxonomy classification categories");
2939 assert_eq!(tool, "galaxy.taxonomy");
2940 }
2941
2942 #[test]
2943 fn classify_galaxy_purge_routes_correctly() {
2944 let (tool, _conf) = classify("purge wipe clear galaxy");
2945 assert_eq!(tool, "galaxy.purge");
2946 }
2947
2948 #[test]
2949 fn classify_galaxy_health_routes_correctly() {
2950 let (tool, _conf) = classify("galaxy health diagnostic checkup");
2951 assert_eq!(tool, "galaxy.health");
2952 }
2953
2954 #[test]
2955 fn classify_memory_sort_routes_correctly() {
2956 let (tool, _conf) = classify("sort memories by importance");
2957 assert_eq!(tool, "memory.sort");
2958 }
2959
2960 #[test]
2961 fn classify_memory_filter_routes_correctly() {
2962 let (tool, _conf) = classify("filter memories by tag criteria");
2963 assert_eq!(tool, "memory.filter");
2964 }
2965
2966 #[test]
2967 fn classify_memory_deduplicate_routes_correctly() {
2968 let (tool, _conf) = classify("deduplicate memories redundant duplicate");
2969 assert_eq!(tool, "memory.deduplicate");
2970 }
2971
2972 #[test]
2973 fn classify_memory_export_routes_correctly() {
2974 let (tool, _conf) = classify("export memories csv format download");
2975 assert_eq!(tool, "memory.export");
2976 }
2977
2978 #[test]
2979 fn classify_homeostasis_check_routes_correctly() {
2980 let (tool, _conf) = classify("homeostasis check balance vitals metrics");
2981 assert_eq!(tool, "homeostasis.check");
2982 }
2983
2984 #[test]
2985 fn classify_homeostasis_adjust_routes_correctly() {
2986 let (tool, _conf) = classify("homeostasis adjust rebalance weight tune");
2987 assert_eq!(tool, "homeostasis.adjust");
2988 }
2989
2990 #[test]
2991 fn classify_homeostasis_history_routes_correctly() {
2992 let (tool, _conf) = classify("homeostasis history trend past samples");
2993 assert_eq!(tool, "homeostasis.history");
2994 }
2995
2996 #[test]
2997 fn classify_homeostasis_alerts_routes_correctly() {
2998 let (tool, _conf) = classify("homeostasis alerts warning critical threshold");
2999 assert_eq!(tool, "homeostasis.alerts");
3000 }
3001
3002 #[test]
3003 fn classify_reflex_dispatch_routes_correctly() {
3004 let (tool, _conf) = classify("dispatch reflex e_stop emergency handler");
3005 assert_eq!(tool, "reflex.dispatch");
3006 }
3007
3008 #[test]
3009 fn classify_reflex_status_routes_correctly() {
3010 let (tool, _conf) = classify("reflex status table registered handlers");
3011 assert_eq!(tool, "reflex.status");
3012 }
3013
3014 #[test]
3015 fn classify_workspace_spotlight_routes_correctly() {
3016 let (tool, _conf) = classify("workspace spotlight attention arbitration");
3017 assert_eq!(tool, "workspace.spotlight");
3018 }
3019
3020 #[test]
3021 fn classify_workspace_events_routes_correctly() {
3022 let (tool, _conf) = classify("workspace recent events backlog history");
3023 assert_eq!(tool, "workspace.events");
3024 }
3025
3026 #[test]
3027 fn classify_workspace_publish_routes_correctly() {
3028 let (tool, _conf) = classify("publish broadcast workspace event emit");
3029 assert_eq!(tool, "workspace.publish");
3030 }
3031
3032 #[test]
3033 fn classify_workspace_stats_routes_correctly() {
3034 let (tool, _conf) = classify("workspace stats statistics transfers count");
3035 assert_eq!(tool, "workspace.stats");
3036 }
3037
3038 #[test]
3039 fn classify_timescale_status_routes_correctly() {
3040 let (tool, _conf) = classify("timescale status tier bus brain_wave active");
3041 assert_eq!(tool, "timescale.status");
3042 }
3043
3044 #[test]
3045 fn classify_timescale_hooks_routes_correctly() {
3046 let (tool, _conf) = classify("timescale hooks list tick timeout performance");
3047 assert_eq!(tool, "timescale.hooks");
3048 }
3049
3050 #[test]
3051 fn classify_confidence_is_reasonable() {
3052 let (_tool, conf) = classify("remember that rust is fast");
3053 assert!(
3054 conf > 0.15,
3055 "confidence should be > 0.15 for clear match, got {conf}"
3056 );
3057 }
3058
3059 #[test]
3060 fn classify_case_insensitive() {
3061 let (tool1, _) = classify("REMEMBER THAT");
3062 let (tool2, _) = classify("remember that");
3063 assert_eq!(tool1, tool2);
3064 }
3065
3066 #[test]
3067 fn classify_partial_match_works() {
3068 let (tool, conf) = classify("search rust");
3069 assert_eq!(tool, "memory.search");
3070 assert!(conf > 0.0);
3071 }
3072
3073 #[test]
3074 fn classify_multi_word_query() {
3075 let (tool, _conf) = classify("show me the effectiveness report for tools");
3076 assert_eq!(tool, "tools.effectiveness_report");
3077 }
3078
3079 #[test]
3080 fn profile_count_is_reasonable() {
3081 assert!(
3083 profile_count() >= 60,
3084 "expected 60+ profiles, got {}",
3085 profile_count()
3086 );
3087 }
3088
3089 #[test]
3090 fn profiled_tools_are_unique() {
3091 let tools = profiled_tools();
3092 let set: HashSet<&str> = tools.iter().copied().collect();
3093 assert_eq!(tools.len(), set.len(), "duplicate tool names in profiles");
3094 }
3095
3096 #[test]
3097 fn classify_unique_patterns_count() {
3098 let inputs = [
3099 "remember",
3100 "recall",
3101 "list memories",
3102 "delete memory",
3103 "search",
3104 "query",
3105 "associate",
3106 "associations",
3107 "consolidate",
3108 "decay",
3109 "batch read",
3110 "update memory",
3111 "tag memory",
3112 "memory stats",
3113 "hybrid recall",
3114 "count memories",
3115 "list tags",
3116 "mine associations",
3117 "start session",
3118 "checkpoint",
3119 "recall session",
3120 "end session",
3121 "list sessions",
3122 "citta status",
3123 "reflect",
3124 "coherence",
3125 "dream status",
3126 "trigger dream",
3127 "effectiveness",
3128 "retire tool",
3129 "pattern search",
3130 "salience",
3131 "serendipity",
3132 "detect clusters",
3133 "list constellations",
3134 "galaxy stats",
3135 "export galaxy",
3136 "import galaxy",
3137 "karma",
3138 "karma history",
3139 "clear karma",
3140 "dharma rules",
3141 "dharma audit",
3142 "dharma profiles",
3143 "dharma",
3144 "register agent",
3145 "list agents",
3146 "heartbeat",
3147 "distribute task",
3148 "task status",
3149 "system health",
3150 "system config",
3151 "flush",
3152 "tools",
3153 "nearby memories",
3154 "vector search",
3155 "find similar",
3156 "extract entities knowledge graph",
3157 "knowledge graph query",
3158 "top hub nodes",
3159 "traverse graph walk",
3160 "detect communities",
3161 "propagate activation",
3162 "transfer galaxy",
3163 "merge galaxies",
3164 "snapshot galaxy",
3165 "restore galaxy",
3166 "sort memories",
3167 "filter memories",
3168 "deduplicate memories",
3169 "export memories csv",
3170 "homeostasis check",
3171 "homeostasis adjust",
3172 "homeostasis history",
3173 "homeostasis alerts",
3174 "dispatch reflex e_stop",
3175 "reflex status table",
3176 "workspace spotlight attention",
3177 "workspace recent events",
3178 "publish workspace event",
3179 "workspace stats summary",
3180 "timescale status tiers",
3181 "timescale hooks tick",
3182 ];
3183 let mut tools: HashSet<&str> = HashSet::new();
3184 for input in &inputs {
3185 let (tool, _) = classify(input);
3186 tools.insert(tool);
3187 }
3188 assert!(
3189 tools.len() >= 30,
3190 "Expected 30+ unique NLU targets, got {}",
3191 tools.len()
3192 );
3193 }
3194
3195 #[test]
3196 fn classify_vector_search_routes_correctly() {
3197 let (tool, conf) = classify("vector search similar memories");
3198 assert_eq!(tool, "memory.vector.search");
3199 assert!(conf > 0.0);
3200 }
3201
3202 #[test]
3203 fn classify_embedding_search_routes_correctly() {
3204 let (tool, conf) = classify("embedding similarity lookup");
3205 assert_eq!(tool, "memory.vector.search");
3206 assert!(conf > 0.0);
3207 }
3208
3209 #[test]
3210 fn classify_semantic_search_routes_correctly() {
3211 let (tool, conf) = classify("semantic similarity search");
3212 assert_eq!(tool, "memory.vector.search");
3213 assert!(conf > 0.0);
3214 }
3215
3216 #[test]
3217 fn classify_stemming_handles_morphological_variants() {
3218 let (tool1, _) = classify("searching for rust");
3220 let (tool2, _) = classify("search for rust");
3221 assert_eq!(tool1, tool2);
3222
3223 let (tool3, _) = classify("stored important fact");
3225 let (tool4, _) = classify("store important fact");
3226 assert_eq!(tool3, tool4);
3227
3228 let (tool5, _) = classify("list memories");
3230 let (tool6, _) = classify("list memory");
3231 assert_eq!(tool5, tool6);
3232 }
3233
3234 #[test]
3235 fn stem_handles_unicode_without_panicking() {
3236 assert_eq!(stem("xéing"), "xé");
3239 assert_eq!(stem("éing"), "é");
3240 assert_eq!(stem("caféing"), "café");
3241 assert_eq!(stem("running"), "run");
3243 assert_eq!(stem("swimming"), "swim");
3244 assert_eq!(stem("searching"), "search");
3245 assert_eq!(stem("typing"), "typ");
3246 assert_eq!(stem("memories"), "memory");
3247 assert_eq!(stem("stored"), "store");
3248 }
3249
3250 #[test]
3251 fn classify_handles_unicode_thoughts_without_panicking() {
3252 let (tool, _conf) = classify("caféing sur les mémoires");
3254 assert!(!tool.is_empty());
3255 let (tool2, _conf2) = classify("mémoire éing recherche");
3256 assert!(!tool2.is_empty());
3257 }
3258
3259 #[test]
3260 fn classify_confidence_improved_with_stopwords() {
3261 let (_, conf) = classify("remember that rust is fast");
3263 assert!(
3264 conf > 0.20,
3265 "confidence should be > 0.20 with stopword filtering, got {conf}"
3266 );
3267 }
3268
3269 #[test]
3272 fn classify_forecast_routes_to_selfmodel_forecast() {
3273 let (tool, _conf) = classify("forecast cpu load for next 5 samples");
3274 assert_eq!(tool, "selfmodel.forecast");
3275 }
3276
3277 #[test]
3278 fn classify_predict_routes_to_selfmodel_forecast() {
3279 let (tool, _conf) = classify("predict memory pressure trend");
3280 assert_eq!(tool, "selfmodel.forecast");
3281 }
3282
3283 #[test]
3284 fn classify_alerts_routes_to_selfmodel_alerts() {
3285 let (tool, _conf) = classify("selfmodel alerts");
3286 assert_eq!(tool, "selfmodel.alerts");
3287 }
3288
3289 #[test]
3290 fn classify_warning_routes_to_selfmodel_alerts() {
3291 let (tool, _conf) = classify("selfmodel critical warnings");
3292 assert_eq!(tool, "selfmodel.alerts");
3293 }
3294
3295 #[test]
3296 fn classify_snapshot_routes_to_selfmodel_snapshot() {
3297 let (tool, _conf) = classify("selfmodel snapshot");
3298 assert_eq!(tool, "selfmodel.snapshot");
3299 }
3300
3301 #[test]
3302 fn classify_introspection_routes_to_selfmodel_snapshot() {
3303 let (tool, _conf) = classify("show introspection state overview");
3304 assert_eq!(tool, "selfmodel.snapshot");
3305 }
3306
3307 #[test]
3310 fn classify_bicameral_debate_routes_to_bicameral_reason() {
3311 let (tool, _conf) = classify("bicameral debate on rust vs python");
3312 assert_eq!(tool, "bicameral.reason");
3313 }
3314
3315 #[test]
3316 fn classify_hemisphere_consensus_routes_to_bicameral_reason() {
3317 let (tool, _conf) = classify("dual hemisphere consensus deliberation");
3318 assert_eq!(tool, "bicameral.reason");
3319 }
3320
3321 #[test]
3322 fn classify_bicameral_status_routes_correctly() {
3323 let (tool, _conf) = classify("bicameral hemisphere status");
3324 assert_eq!(tool, "bicameral.status");
3325 }
3326
3327 #[test]
3328 fn classify_callosum_routes_to_bicameral_reason() {
3329 let (tool, _conf) = classify("corpus callosum debate perspectives");
3330 assert_eq!(tool, "bicameral.reason");
3331 }
3332
3333 #[test]
3336 fn classify_drive_snapshot_routes_correctly() {
3337 let (tool, _conf) = classify("drive snapshot current motivation state");
3338 assert_eq!(tool, "drive.snapshot");
3339 }
3340
3341 #[test]
3342 fn classify_emotion_routes_to_drive_snapshot() {
3343 let (tool, _conf) = classify("show current emotion and mood");
3344 assert_eq!(tool, "drive.snapshot");
3345 }
3346
3347 #[test]
3348 fn classify_drive_event_routes_correctly() {
3349 let (tool, _conf) = classify("inject drive event reward for success");
3350 assert_eq!(tool, "drive.event");
3351 }
3352
3353 #[test]
3354 fn classify_curiosity_routes_to_drive_snapshot() {
3355 let (tool, _conf) = classify("curiosity satisfaction caution levels");
3356 assert_eq!(tool, "drive.snapshot");
3357 }
3358
3359 #[test]
3362 fn adversarial_remember_in_redteam_query_doesnt_misroute() {
3363 let (tool, _conf) = classify("redteam scan to remember uncovered vectors");
3365 assert_ne!(
3366 tool, "memory.create",
3367 "redteam query should not route to memory.create even with 'remember' embedded"
3368 );
3369 }
3370
3371 #[test]
3372 fn adversarial_delete_in_search_query_doesnt_misroute() {
3373 let (tool, _conf) = classify("search for memories about delete operations");
3375 assert_ne!(
3376 tool, "memory.delete",
3377 "search query should not route to memory.delete even with 'delete' embedded"
3378 );
3379 }
3380
3381 #[test]
3382 fn adversarial_store_in_gnosis_query_doesnt_misroute() {
3383 let (tool, _conf) = classify("explain why the store blocked my action");
3385 assert_ne!(
3386 tool, "memory.create",
3387 "gnosis query should not route to memory.create even with 'store' embedded"
3388 );
3389 }
3390
3391 #[test]
3392 fn adversarial_repeated_keyword_doesnt_inflate_score() {
3393 let (tool, conf) = classify("remember remember remember remember remember remember");
3395 assert_eq!(tool, "memory.create");
3396 assert!(
3398 conf <= 1.0,
3399 "repeated keywords should not inflate confidence beyond 1.0: got {conf}"
3400 );
3401 }
3402
3403 #[test]
3404 fn adversarial_keyword_stuffing_doesnt_misroute() {
3405 let (tool, _conf) = classify("remember delete search list recall store");
3407 assert!(
3409 tool.starts_with("memory."),
3410 "keyword stuffing should still route to a memory tool, got {tool}"
3411 );
3412 }
3413
3414 #[test]
3415 fn adversarial_redteam_with_memory_keyword_doesnt_misroute() {
3416 let (tool, _conf) = classify("redteam proposals for memory poisoning attack");
3418 assert_eq!(
3419 tool, "redteam.proposals",
3420 "redteam query should route to redteam.proposals even with 'memory' embedded"
3421 );
3422 }
3423
3424 #[test]
3425 fn adversarial_friction_with_delete_keyword_doesnt_misroute() {
3426 let (tool, _conf) = classify("log friction about delete operations failing");
3428 assert_ne!(
3430 tool, "memory.delete",
3431 "friction query should not route to memory.delete even with 'delete' embedded"
3432 );
3433 }
3434
3435 #[test]
3436 fn adversarial_long_input_doesnt_cascade_misroute() {
3437 let input = "remember to search for delete and list and recall and store and save \
3439 and memorize and retrieve and fetch and get and load and access and \
3440 query and find and look and check and count and purge and forget \
3441 and remove and drop and clear and wipe and erase and destroy";
3442 let (tool, _conf) = classify(input);
3443 assert!(
3445 tool.starts_with("memory.") || tool == "gnosis",
3446 "long input should route to memory tool or gnosis, got {tool}"
3447 );
3448 }
3449
3450 #[test]
3451 fn adversarial_empty_words_between_keywords() {
3452 let (tool1, _) = classify("remember the important fact");
3454 let (tool2, _) = classify("remember the important fact");
3455 assert_eq!(tool1, tool2, "extra whitespace should not change routing");
3456 }
3457
3458 #[test]
3459 fn adversarial_unicode_homoglyph_doesnt_misroute() {
3460 let (tool, _conf) = classify("rеmеmbеr this fact"); assert_ne!(
3465 tool, "memory.create",
3466 "unicode homoglyphs should not trick the router into memory.create"
3467 );
3468 }
3469
3470 #[test]
3473 fn classify_imagine_scenarios_routes_to_imagine_scenario() {
3474 let (tool, _conf) = classify("imagine scenarios for improving performance");
3475 assert_eq!(tool, "imagine.scenario");
3476 }
3477
3478 #[test]
3479 fn classify_brainstorm_routes_to_imagine_scenario() {
3480 let (tool, _conf) = classify("brainstorm contingency plans for deployment");
3481 assert_eq!(tool, "imagine.scenario");
3482 }
3483
3484 #[test]
3485 fn classify_envision_routes_to_imagine_scenario() {
3486 let (tool, _conf) = classify("envision what-if possibilities for the system");
3487 assert_eq!(tool, "imagine.scenario");
3488 }
3489
3490 #[test]
3491 fn classify_reflect_routes_to_imagine_reflect() {
3492 let (tool, _conf) =
3493 classify("counterfactual reflect on what should have been done instead");
3494 assert_eq!(tool, "imagine.reflect");
3495 }
3496
3497 #[test]
3498 fn classify_counterfactual_routes_to_imagine_reflect() {
3499 let (tool, _conf) = classify("counterfactual analysis of the decision");
3500 assert_eq!(tool, "imagine.reflect");
3501 }
3502
3503 use proptest::prelude::*;
3506
3507 proptest! {
3508 #[test]
3510 fn classify_never_panics(text in ".*") {
3511 let (tool, conf) = classify(&text);
3512 prop_assert!(!tool.is_empty(), "tool name must be non-empty");
3513 prop_assert!(
3514 (0.0..=1.0).contains(&conf),
3515 "confidence must be in [0,1], got {conf}"
3516 );
3517 }
3518
3519 #[test]
3521 fn classify_never_panics_bytes(data in proptest::collection::vec(any::<u8>(), 0..256)) {
3522 let text = String::from_utf8_lossy(&data);
3523 let (tool, conf) = classify(&text);
3524 prop_assert!(!tool.is_empty());
3525 prop_assert!((0.0..=1.0).contains(&conf));
3526 }
3527
3528 #[test]
3530 fn classify_is_deterministic(text in ".*") {
3531 let (tool1, conf1) = classify(&text);
3532 let (tool2, conf2) = classify(&text);
3533 prop_assert_eq!(tool1, tool2);
3534 prop_assert!((conf1 - conf2).abs() < f64::EPSILON);
3535 }
3536
3537 #[test]
3539 fn classify_empty_returns_gnosis_prop(ws in r"[ \t\n\r]*") {
3540 let (tool, conf) = classify(&ws);
3541 prop_assert_eq!(tool, "gnosis");
3542 prop_assert_eq!(conf, 0.0);
3543 }
3544
3545 #[test]
3547 fn classify_confidence_is_finite(text in ".*") {
3548 let (_, conf) = classify(&text);
3549 prop_assert!(conf.is_finite(), "confidence must be finite, got {conf}");
3550 }
3551 }
3552}