1use super::ToolDefinition;
6
7pub fn capture_tool() -> ToolDefinition {
9 ToolDefinition {
10 name: "subcog_capture".to_string(),
11 description: "Capture a memory (decision, learning, pattern, etc.) for future recall"
12 .to_string(),
13 input_schema: serde_json::json!({
14 "type": "object",
15 "properties": {
16 "content": {
17 "type": "string",
18 "description": "The memory content to capture"
19 },
20 "namespace": {
21 "type": "string",
22 "description": "Memory category: decisions, patterns, learnings, context, tech-debt, apis, config, security, performance, testing",
23 "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
24 },
25 "tags": {
26 "type": "array",
27 "items": { "type": "string" },
28 "description": "Optional tags for categorization"
29 },
30 "source": {
31 "type": "string",
32 "description": "Optional source reference (file path, URL)"
33 },
34 "ttl": {
35 "type": "string",
36 "description": "Optional TTL for automatic expiration. Supports: '7d' (days), '24h' (hours), '60m' (minutes), '3600s' or '3600' (seconds), '0' (never expire)"
37 },
38 "domain": {
39 "type": "string",
40 "description": "Storage scope: 'project' (default, stored with project context), 'user' (global across all projects), 'org' (organization-shared)",
41 "enum": ["project", "user", "org"],
42 "default": "project"
43 }
44 },
45 "required": ["content", "namespace"]
46 }),
47 }
48}
49
50pub fn recall_tool() -> ToolDefinition {
55 ToolDefinition {
56 name: "subcog_recall".to_string(),
57 description: "Search for relevant memories using semantic and text search, or list all memories when no query is provided. Returns normalized scores (0.0-1.0 where 1.0 is the best match) with raw RRF scores shown in parentheses for debugging. Subsumes subcog_list functionality.".to_string(),
58 input_schema: serde_json::json!({
59 "type": "object",
60 "additionalProperties": false,
61 "properties": {
62 "query": {
63 "type": "string",
64 "description": "The search query. If omitted, lists all memories matching the filter criteria."
65 },
66 "filter": {
67 "type": "string",
68 "description": "Filter query using GitHub-style syntax: ns:decisions tag:rust -tag:test since:7d source:src/*"
69 },
70 "namespace": {
71 "type": "string",
72 "description": "Optional: Filter by namespace (deprecated, use filter instead)",
73 "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
74 },
75 "mode": {
76 "type": "string",
77 "description": "Search mode: hybrid (default), vector, text",
78 "enum": ["hybrid", "vector", "text"]
79 },
80 "detail": {
81 "type": "string",
82 "description": "Detail level: light (frontmatter only), medium (+ summary), everything (full content). Default: medium",
83 "enum": ["light", "medium", "everything"]
84 },
85 "limit": {
86 "type": "integer",
87 "description": "Maximum number of results (default: 10 for search, 50 for list)",
88 "minimum": 1,
89 "maximum": 1000
90 },
91 "entity": {
92 "type": "string",
93 "description": "Filter by entity names (memories mentioning these entities). Comma-separated for OR logic (e.g., 'PostgreSQL,Redis')"
94 },
95 "offset": {
96 "type": "integer",
97 "description": "Offset for pagination (default: 0). Used when listing without query.",
98 "minimum": 0,
99 "default": 0
100 },
101 "user_id": {
102 "type": "string",
103 "description": "Filter by user ID (for multi-tenant scoping)"
104 },
105 "agent_id": {
106 "type": "string",
107 "description": "Filter by agent ID (for multi-agent scoping)"
108 }
109 },
110 "required": []
111 }),
112 }
113}
114
115pub fn status_tool() -> ToolDefinition {
117 ToolDefinition {
118 name: "subcog_status".to_string(),
119 description: "Get memory system status and statistics".to_string(),
120 input_schema: serde_json::json!({
121 "type": "object",
122 "properties": {},
123 "required": []
124 }),
125 }
126}
127
128pub fn prompt_understanding_tool() -> ToolDefinition {
130 ToolDefinition {
131 name: "prompt_understanding".to_string(),
132 description: "Detailed guidance for using Subcog MCP tools effectively".to_string(),
133 input_schema: serde_json::json!({
134 "type": "object",
135 "properties": {},
136 "required": []
137 }),
138 }
139}
140
141pub fn namespaces_tool() -> ToolDefinition {
143 ToolDefinition {
144 name: "subcog_namespaces".to_string(),
145 description: "List available memory namespaces and their descriptions".to_string(),
146 input_schema: serde_json::json!({
147 "type": "object",
148 "properties": {},
149 "required": []
150 }),
151 }
152}
153
154pub fn consolidate_tool() -> ToolDefinition {
156 ToolDefinition {
157 name: "subcog_consolidate".to_string(),
158 description: "Consolidate related memories by finding semantic clusters and creating summary nodes. Returns consolidation statistics.".to_string(),
159 input_schema: serde_json::json!({
160 "type": "object",
161 "properties": {
162 "namespaces": {
163 "type": "array",
164 "items": {
165 "type": "string",
166 "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
167 },
168 "description": "Namespaces to consolidate (optional, defaults to all)"
169 },
170 "days": {
171 "type": "integer",
172 "description": "Time window in days for memories to consolidate (optional)",
173 "minimum": 1
174 },
175 "dry_run": {
176 "type": "boolean",
177 "description": "If true, show what would be consolidated without making changes",
178 "default": false
179 },
180 "min_memories": {
181 "type": "integer",
182 "description": "Minimum number of memories required to form a group (optional, default: 3)",
183 "minimum": 2
184 },
185 "similarity": {
186 "type": "number",
187 "description": "Similarity threshold 0.0-1.0 for grouping related memories (optional, default: 0.7)",
188 "minimum": 0.0,
189 "maximum": 1.0
190 }
191 },
192 "required": []
193 }),
194 }
195}
196
197pub fn get_summary_tool() -> ToolDefinition {
199 ToolDefinition {
200 name: "subcog_get_summary".to_string(),
201 description: "Retrieve a summary node and its linked source memories. Uses edge relationships to show which memories were consolidated into the summary.".to_string(),
202 input_schema: serde_json::json!({
203 "type": "object",
204 "properties": {
205 "memory_id": {
206 "type": "string",
207 "description": "ID of the summary memory to retrieve"
208 }
209 },
210 "required": ["memory_id"]
211 }),
212 }
213}
214
215pub fn enrich_tool() -> ToolDefinition {
217 ToolDefinition {
218 name: "subcog_enrich".to_string(),
219 description: "Enrich a memory with better structure, tags, and context using LLM. Uses MCP sampling to request LLM completion.".to_string(),
220 input_schema: serde_json::json!({
221 "type": "object",
222 "properties": {
223 "memory_id": {
224 "type": "string",
225 "description": "ID of the memory to enrich"
226 },
227 "enrich_tags": {
228 "type": "boolean",
229 "description": "Generate or improve tags",
230 "default": true
231 },
232 "enrich_structure": {
233 "type": "boolean",
234 "description": "Restructure content for clarity",
235 "default": true
236 },
237 "add_context": {
238 "type": "boolean",
239 "description": "Add inferred context and rationale",
240 "default": false
241 }
242 },
243 "required": ["memory_id"]
244 }),
245 }
246}
247
248pub fn sync_tool() -> ToolDefinition {
253 ToolDefinition {
254 name: "subcog_sync".to_string(),
255 description: "[DEPRECATED] Sync memories with git remote. No longer needed as SQLite is now authoritative storage. This tool is a no-op and will be removed in a future version.".to_string(),
256 input_schema: serde_json::json!({
257 "type": "object",
258 "properties": {
259 "direction": {
260 "type": "string",
261 "description": "Sync direction: push (upload), fetch (download), full (both)",
262 "enum": ["push", "fetch", "full"],
263 "default": "full"
264 }
265 },
266 "required": []
267 }),
268 }
269}
270
271pub fn reindex_tool() -> ToolDefinition {
273 ToolDefinition {
274 name: "subcog_reindex".to_string(),
275 description: "Rebuild the search index from stored memories. Use when index is out of sync with stored memories.".to_string(),
276 input_schema: serde_json::json!({
277 "type": "object",
278 "properties": {
279 "repo_path": {
280 "type": "string",
281 "description": "Path to git repository (default: current directory)"
282 }
283 },
284 "required": []
285 }),
286 }
287}
288
289pub fn gdpr_export_tool() -> ToolDefinition {
293 ToolDefinition {
294 name: "subcog_gdpr_export".to_string(),
295 description: "Export all user data in a portable JSON format (GDPR Article 20 - Right to Data Portability). Returns all memories with metadata for download or transfer to another system.".to_string(),
296 input_schema: serde_json::json!({
297 "type": "object",
298 "properties": {},
299 "required": []
300 }),
301 }
302}
303
304pub fn prompts_tool() -> ToolDefinition {
312 ToolDefinition {
313 name: "subcog_prompts".to_string(),
314 description: "Manage prompt templates. Actions: save, list, get, run, delete.".to_string(),
315 input_schema: serde_json::json!({
316 "type": "object",
317 "properties": {
318 "action": {
319 "type": "string",
320 "description": "Operation to perform",
321 "enum": ["save", "list", "get", "run", "delete"]
322 },
323 "name": {
324 "type": "string",
325 "description": "Prompt name (required for save/get/run/delete)"
326 },
327 "content": {
328 "type": "string",
329 "description": "Prompt content with {{variable}} placeholders (for save, required if file_path not provided)"
330 },
331 "file_path": {
332 "type": "string",
333 "description": "Path to file containing prompt (for save, alternative to content)"
334 },
335 "description": {
336 "type": "string",
337 "description": "Human-readable description (for save)"
338 },
339 "tags": {
340 "type": "array",
341 "items": { "type": "string" },
342 "description": "Tags for categorization (for save/list)"
343 },
344 "domain": {
345 "type": "string",
346 "description": "Storage scope: project (default), user, or org",
347 "enum": ["project", "user", "org"],
348 "default": "project"
349 },
350 "variables_def": {
351 "type": "array",
352 "description": "Variable definitions with metadata (for save)",
353 "items": {
354 "type": "object",
355 "properties": {
356 "name": { "type": "string" },
357 "description": { "type": "string" },
358 "default": { "type": "string" },
359 "required": { "type": "boolean", "default": true }
360 },
361 "required": ["name"]
362 }
363 },
364 "variables": {
365 "type": "object",
366 "description": "Variable values to substitute (for run)",
367 "additionalProperties": { "type": "string" }
368 },
369 "skip_enrichment": {
370 "type": "boolean",
371 "description": "Skip LLM-powered metadata enrichment (for save)",
372 "default": false
373 },
374 "name_pattern": {
375 "type": "string",
376 "description": "Filter by name pattern (for list, glob-style)"
377 },
378 "limit": {
379 "type": "integer",
380 "description": "Maximum number of results (for list)",
381 "minimum": 1,
382 "maximum": 100,
383 "default": 20
384 }
385 },
386 "required": ["action"]
387 }),
388 }
389}
390
391pub fn prompt_save_tool() -> ToolDefinition {
393 ToolDefinition {
394 name: "prompt_save".to_string(),
395 description: "Save a user-defined prompt template. Provide either 'content' or 'file_path' (not both)".to_string(),
396 input_schema: serde_json::json!({
397 "type": "object",
398 "properties": {
399 "name": {
400 "type": "string",
401 "description": "Unique prompt name (kebab-case, e.g., 'code-review')"
402 },
403 "content": {
404 "type": "string",
405 "description": "Prompt content with {{variable}} placeholders (required if file_path not provided)"
406 },
407 "file_path": {
408 "type": "string",
409 "description": "Path to file containing prompt (alternative to content)"
410 },
411 "description": {
412 "type": "string",
413 "description": "Human-readable description of the prompt"
414 },
415 "tags": {
416 "type": "array",
417 "items": { "type": "string" },
418 "description": "Tags for categorization and search"
419 },
420 "domain": {
421 "type": "string",
422 "description": "Storage scope: project (default), user, or org",
423 "enum": ["project", "user", "org"],
424 "default": "project"
425 },
426 "variables": {
427 "type": "array",
428 "description": "Explicit variable definitions with metadata",
429 "items": {
430 "type": "object",
431 "properties": {
432 "name": { "type": "string", "description": "Variable name (without braces)" },
433 "description": { "type": "string", "description": "Human-readable description" },
434 "default": { "type": "string", "description": "Default value if not provided" },
435 "required": { "type": "boolean", "default": true, "description": "Whether variable is required" }
436 },
437 "required": ["name"]
438 }
439 },
440 "skip_enrichment": {
441 "type": "boolean",
442 "description": "Skip LLM-powered metadata enrichment (default: false)",
443 "default": false
444 }
445 },
446 "required": ["name"],
447 "additionalProperties": false
448 }),
449 }
450}
451
452pub fn prompt_list_tool() -> ToolDefinition {
454 ToolDefinition {
455 name: "prompt_list".to_string(),
456 description: "List saved prompt templates with optional filtering".to_string(),
457 input_schema: serde_json::json!({
458 "type": "object",
459 "properties": {
460 "domain": {
461 "type": "string",
462 "description": "Filter by domain scope",
463 "enum": ["project", "user", "org"]
464 },
465 "tags": {
466 "type": "array",
467 "items": { "type": "string" },
468 "description": "Filter by tags (AND logic - must have all)"
469 },
470 "name_pattern": {
471 "type": "string",
472 "description": "Filter by name pattern (glob-style, e.g., 'code-*')"
473 },
474 "limit": {
475 "type": "integer",
476 "description": "Maximum number of results",
477 "minimum": 1,
478 "maximum": 100,
479 "default": 20
480 }
481 },
482 "required": []
483 }),
484 }
485}
486
487pub fn prompt_get_tool() -> ToolDefinition {
489 ToolDefinition {
490 name: "prompt_get".to_string(),
491 description: "Get a prompt template by name".to_string(),
492 input_schema: serde_json::json!({
493 "type": "object",
494 "properties": {
495 "name": {
496 "type": "string",
497 "description": "Prompt name to retrieve"
498 },
499 "domain": {
500 "type": "string",
501 "description": "Domain to search (if not specified, searches Project → User → Org)",
502 "enum": ["project", "user", "org"]
503 }
504 },
505 "required": ["name"]
506 }),
507 }
508}
509
510pub fn prompt_run_tool() -> ToolDefinition {
512 ToolDefinition {
513 name: "prompt_run".to_string(),
514 description: "Run a saved prompt, substituting variable values".to_string(),
515 input_schema: serde_json::json!({
516 "type": "object",
517 "properties": {
518 "name": {
519 "type": "string",
520 "description": "Prompt name to run"
521 },
522 "variables": {
523 "type": "object",
524 "description": "Variable values to substitute (key: value pairs)",
525 "additionalProperties": { "type": "string" }
526 },
527 "domain": {
528 "type": "string",
529 "description": "Domain to search for the prompt",
530 "enum": ["project", "user", "org"]
531 }
532 },
533 "required": ["name"]
534 }),
535 }
536}
537
538pub fn prompt_delete_tool() -> ToolDefinition {
540 ToolDefinition {
541 name: "prompt_delete".to_string(),
542 description: "Delete a saved prompt template".to_string(),
543 input_schema: serde_json::json!({
544 "type": "object",
545 "properties": {
546 "name": {
547 "type": "string",
548 "description": "Prompt name to delete"
549 },
550 "domain": {
551 "type": "string",
552 "description": "Domain scope to delete from (required for safety)",
553 "enum": ["project", "user", "org"]
554 }
555 },
556 "required": ["name", "domain"]
557 }),
558 }
559}
560
561pub fn get_tool() -> ToolDefinition {
572 ToolDefinition {
573 name: "subcog_get".to_string(),
574 description: "Get a memory by its ID. Returns the full memory content, metadata, and URN."
575 .to_string(),
576 input_schema: serde_json::json!({
577 "type": "object",
578 "properties": {
579 "memory_id": {
580 "type": "string",
581 "description": "The ID of the memory to retrieve"
582 }
583 },
584 "required": ["memory_id"]
585 }),
586 }
587}
588
589pub fn delete_tool() -> ToolDefinition {
594 ToolDefinition {
595 name: "subcog_delete".to_string(),
596 description: "Delete a memory by its ID. Defaults to soft delete (tombstone) which can be restored. Use hard=true for permanent deletion.".to_string(),
597 input_schema: serde_json::json!({
598 "type": "object",
599 "properties": {
600 "memory_id": {
601 "type": "string",
602 "description": "The ID of the memory to delete"
603 },
604 "hard": {
605 "type": "boolean",
606 "description": "If true, permanently delete the memory. If false (default), soft delete (tombstone) - can be restored later.",
607 "default": false
608 }
609 },
610 "required": ["memory_id"]
611 }),
612 }
613}
614
615pub fn update_tool() -> ToolDefinition {
620 ToolDefinition {
621 name: "subcog_update".to_string(),
622 description: "Update an existing memory's content and/or tags. Provide only the fields you want to change.".to_string(),
623 input_schema: serde_json::json!({
624 "type": "object",
625 "properties": {
626 "memory_id": {
627 "type": "string",
628 "description": "The ID of the memory to update"
629 },
630 "content": {
631 "type": "string",
632 "description": "New content for the memory (optional - omit to keep existing)"
633 },
634 "tags": {
635 "type": "array",
636 "items": { "type": "string" },
637 "description": "New tags for the memory (optional - omit to keep existing). Replaces all existing tags when provided."
638 }
639 },
640 "required": ["memory_id"]
641 }),
642 }
643}
644
645pub fn list_tool() -> ToolDefinition {
650 ToolDefinition {
651 name: "subcog_list".to_string(),
652 description: "List all memories with optional filtering and pagination. Unlike recall, this doesn't require a search query.".to_string(),
653 input_schema: serde_json::json!({
654 "type": "object",
655 "properties": {
656 "filter": {
657 "type": "string",
658 "description": "GitHub-style filter query: ns:decisions tag:rust -tag:test status:active"
659 },
660 "limit": {
661 "type": "integer",
662 "description": "Maximum number of results (default: 50, max: 1000)",
663 "minimum": 1,
664 "maximum": 1000,
665 "default": 50
666 },
667 "offset": {
668 "type": "integer",
669 "description": "Offset for pagination (default: 0)",
670 "minimum": 0,
671 "default": 0
672 },
673 "user_id": {
674 "type": "string",
675 "description": "Filter by user ID (for multi-tenant scoping)"
676 },
677 "agent_id": {
678 "type": "string",
679 "description": "Filter by agent ID (for multi-agent scoping)"
680 }
681 },
682 "required": []
683 }),
684 }
685}
686
687pub fn delete_all_tool() -> ToolDefinition {
692 ToolDefinition {
693 name: "subcog_delete_all".to_string(),
694 description: "Bulk delete memories matching filter criteria. Defaults to dry-run mode for safety - set dry_run=false to execute.".to_string(),
695 input_schema: serde_json::json!({
696 "type": "object",
697 "properties": {
698 "filter": {
699 "type": "string",
700 "description": "GitHub-style filter query: ns:decisions tag:deprecated -tag:important"
701 },
702 "dry_run": {
703 "type": "boolean",
704 "description": "If true (default), show what would be deleted without making changes",
705 "default": true
706 },
707 "hard": {
708 "type": "boolean",
709 "description": "If true, permanently delete. If false (default), soft delete (tombstone).",
710 "default": false
711 },
712 "user_id": {
713 "type": "string",
714 "description": "Filter by user ID for scoped deletion"
715 }
716 },
717 "required": []
718 }),
719 }
720}
721
722pub fn restore_tool() -> ToolDefinition {
727 ToolDefinition {
728 name: "subcog_restore".to_string(),
729 description:
730 "Restore a soft-deleted (tombstoned) memory. Returns the memory to active status."
731 .to_string(),
732 input_schema: serde_json::json!({
733 "type": "object",
734 "properties": {
735 "memory_id": {
736 "type": "string",
737 "description": "The ID of the tombstoned memory to restore"
738 }
739 },
740 "required": ["memory_id"]
741 }),
742 }
743}
744
745pub fn history_tool() -> ToolDefinition {
750 ToolDefinition {
751 name: "subcog_history".to_string(),
752 description: "Get the change history for a memory. Shows creation, updates, and deletions from the audit log.".to_string(),
753 input_schema: serde_json::json!({
754 "type": "object",
755 "properties": {
756 "memory_id": {
757 "type": "string",
758 "description": "The ID of the memory to get history for"
759 },
760 "limit": {
761 "type": "integer",
762 "description": "Maximum number of events to return (default: 20)",
763 "minimum": 1,
764 "maximum": 100,
765 "default": 20
766 }
767 },
768 "required": ["memory_id"]
769 }),
770 }
771}
772
773pub fn entities_tool() -> ToolDefinition {
782 ToolDefinition {
783 name: "subcog_entities".to_string(),
784 description: "Manage entities in the knowledge graph. Supports CRUD operations for people, organizations, technologies, concepts, and files.".to_string(),
785 input_schema: serde_json::json!({
786 "type": "object",
787 "properties": {
788 "action": {
789 "type": "string",
790 "description": "Operation to perform",
791 "enum": ["create", "get", "list", "delete"]
792 },
793 "entity_id": {
794 "type": "string",
795 "description": "Entity ID (required for get/delete)"
796 },
797 "name": {
798 "type": "string",
799 "description": "Entity name (required for create)"
800 },
801 "entity_type": {
802 "type": "string",
803 "description": "Type of entity",
804 "enum": ["Person", "Organization", "Technology", "Concept", "File"]
805 },
806 "aliases": {
807 "type": "array",
808 "items": { "type": "string" },
809 "description": "Alternative names for the entity"
810 },
811 "limit": {
812 "type": "integer",
813 "description": "Maximum results for list operation (default: 20)",
814 "minimum": 1,
815 "maximum": 100,
816 "default": 20
817 }
818 },
819 "required": ["action"]
820 }),
821 }
822}
823
824pub fn relationships_tool() -> ToolDefinition {
829 ToolDefinition {
830 name: "subcog_relationships".to_string(),
831 description: "Manage relationships between entities in the knowledge graph. Supports creating, querying, and deleting relationships like WorksAt, Uses, Created, etc.".to_string(),
832 input_schema: serde_json::json!({
833 "type": "object",
834 "properties": {
835 "action": {
836 "type": "string",
837 "description": "Operation to perform",
838 "enum": ["create", "get", "list", "delete"]
839 },
840 "from_entity": {
841 "type": "string",
842 "description": "Source entity ID (required for create)"
843 },
844 "to_entity": {
845 "type": "string",
846 "description": "Target entity ID (required for create)"
847 },
848 "relationship_type": {
849 "type": "string",
850 "description": "Type of relationship",
851 "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
852 },
853 "entity_id": {
854 "type": "string",
855 "description": "Entity ID to get relationships for (for get/list)"
856 },
857 "direction": {
858 "type": "string",
859 "description": "Relationship direction for get/list",
860 "enum": ["outgoing", "incoming", "both"],
861 "default": "both"
862 },
863 "limit": {
864 "type": "integer",
865 "description": "Maximum results (default: 20)",
866 "minimum": 1,
867 "maximum": 100,
868 "default": 20
869 }
870 },
871 "required": ["action"]
872 }),
873 }
874}
875
876pub fn graph_query_tool() -> ToolDefinition {
881 ToolDefinition {
882 name: "subcog_graph_query".to_string(),
883 description: "Query and traverse the knowledge graph. Find paths between entities, get neighbors at various depths, and explore connections.".to_string(),
884 input_schema: serde_json::json!({
885 "type": "object",
886 "properties": {
887 "operation": {
888 "type": "string",
889 "description": "Query operation to perform",
890 "enum": ["neighbors", "path", "stats"]
891 },
892 "entity_id": {
893 "type": "string",
894 "description": "Starting entity ID (required for neighbors)"
895 },
896 "from_entity": {
897 "type": "string",
898 "description": "Source entity ID (required for path)"
899 },
900 "to_entity": {
901 "type": "string",
902 "description": "Target entity ID (required for path)"
903 },
904 "depth": {
905 "type": "integer",
906 "description": "Traversal depth for neighbors/path (default: 2, max: 5)",
907 "minimum": 1,
908 "maximum": 5,
909 "default": 2
910 }
911 },
912 "required": ["operation"]
913 }),
914 }
915}
916
917pub fn extract_entities_tool() -> ToolDefinition {
922 ToolDefinition {
923 name: "subcog_extract_entities".to_string(),
924 description: "Extract entities and relationships from text using LLM. Identifies people, organizations, technologies, concepts, and their relationships. Falls back to pattern-based extraction if LLM unavailable.".to_string(),
925 input_schema: serde_json::json!({
926 "type": "object",
927 "properties": {
928 "content": {
929 "type": "string",
930 "description": "Text content to extract entities from"
931 },
932 "store": {
933 "type": "boolean",
934 "description": "Whether to store extracted entities in the graph (default: false)",
935 "default": false
936 },
937 "memory_id": {
938 "type": "string",
939 "description": "Optional memory ID to link extracted entities to"
940 },
941 "min_confidence": {
942 "type": "number",
943 "description": "Minimum confidence threshold (0.0-1.0, default: 0.5)",
944 "minimum": 0.0,
945 "maximum": 1.0,
946 "default": 0.5
947 }
948 },
949 "required": ["content"]
950 }),
951 }
952}
953
954pub fn entity_merge_tool() -> ToolDefinition {
959 ToolDefinition {
960 name: "subcog_entity_merge".to_string(),
961 description: "Merge duplicate entities into a single canonical entity. Transfers all relationships and mentions to the merged entity. Use 'find_duplicates' to identify candidates first.".to_string(),
962 input_schema: serde_json::json!({
963 "type": "object",
964 "properties": {
965 "action": {
966 "type": "string",
967 "description": "Operation to perform",
968 "enum": ["find_duplicates", "merge"]
969 },
970 "entity_id": {
971 "type": "string",
972 "description": "Entity ID to find duplicates for (for find_duplicates)"
973 },
974 "entity_ids": {
975 "type": "array",
976 "items": { "type": "string" },
977 "description": "Entity IDs to merge (for merge, minimum 2)"
978 },
979 "canonical_name": {
980 "type": "string",
981 "description": "Name for the merged entity (required for merge)"
982 },
983 "threshold": {
984 "type": "number",
985 "description": "Similarity threshold for finding duplicates (0.0-1.0, default: 0.7)",
986 "minimum": 0.0,
987 "maximum": 1.0,
988 "default": 0.7
989 }
990 },
991 "required": ["action"]
992 }),
993 }
994}
995
996pub fn relationship_infer_tool() -> ToolDefinition {
1001 ToolDefinition {
1002 name: "subcog_relationship_infer".to_string(),
1003 description: "Infer implicit relationships between entities using LLM analysis. Discovers connections based on entity types, names, and context. Falls back to heuristic-based inference if LLM unavailable.".to_string(),
1004 input_schema: serde_json::json!({
1005 "type": "object",
1006 "properties": {
1007 "entity_ids": {
1008 "type": "array",
1009 "items": { "type": "string" },
1010 "description": "Entity IDs to analyze for relationships (optional, analyzes all recent if not provided)"
1011 },
1012 "store": {
1013 "type": "boolean",
1014 "description": "Whether to store inferred relationships in the graph (default: false)",
1015 "default": false
1016 },
1017 "min_confidence": {
1018 "type": "number",
1019 "description": "Minimum confidence threshold for inferred relationships (0.0-1.0, default: 0.6)",
1020 "minimum": 0.0,
1021 "maximum": 1.0,
1022 "default": 0.6
1023 },
1024 "limit": {
1025 "type": "integer",
1026 "description": "Maximum entities to analyze if entity_ids not provided (default: 50)",
1027 "minimum": 1,
1028 "maximum": 200,
1029 "default": 50
1030 }
1031 },
1032 "required": []
1033 }),
1034 }
1035}
1036
1037pub fn graph_visualize_tool() -> ToolDefinition {
1042 ToolDefinition {
1043 name: "subcog_graph_visualize".to_string(),
1044 description: "Visualize the knowledge graph or a subgraph. Generates Mermaid diagrams, DOT format, or ASCII art representation of entities and their relationships.".to_string(),
1045 input_schema: serde_json::json!({
1046 "type": "object",
1047 "properties": {
1048 "format": {
1049 "type": "string",
1050 "description": "Output format for visualization",
1051 "enum": ["mermaid", "dot", "ascii"],
1052 "default": "mermaid"
1053 },
1054 "entity_id": {
1055 "type": "string",
1056 "description": "Center visualization on this entity (optional)"
1057 },
1058 "depth": {
1059 "type": "integer",
1060 "description": "Depth of relationships to include from center entity (default: 2)",
1061 "minimum": 1,
1062 "maximum": 4,
1063 "default": 2
1064 },
1065 "entity_types": {
1066 "type": "array",
1067 "items": {
1068 "type": "string",
1069 "enum": ["Person", "Organization", "Technology", "Concept", "File"]
1070 },
1071 "description": "Filter to specific entity types"
1072 },
1073 "relationship_types": {
1074 "type": "array",
1075 "items": {
1076 "type": "string",
1077 "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
1078 },
1079 "description": "Filter to specific relationship types"
1080 },
1081 "limit": {
1082 "type": "integer",
1083 "description": "Maximum entities to include (default: 50)",
1084 "minimum": 1,
1085 "maximum": 200,
1086 "default": 50
1087 }
1088 },
1089 "required": []
1090 }),
1091 }
1092}
1093
1094pub fn graph_tool() -> ToolDefinition {
1099 ToolDefinition {
1100 name: "subcog_graph".to_string(),
1101 description: "Consolidated knowledge graph operations. Query graph structure (neighbors, paths, stats) or generate visualizations. Combines subcog_graph_query and subcog_graph_visualize.".to_string(),
1102 input_schema: serde_json::json!({
1103 "type": "object",
1104 "additionalProperties": false,
1105 "properties": {
1106 "operation": {
1107 "type": "string",
1108 "description": "Graph operation to perform",
1109 "enum": ["neighbors", "path", "stats", "visualize"]
1110 },
1111 "entity_id": {
1112 "type": "string",
1113 "description": "Entity ID for neighbors/visualize operations (center point)"
1114 },
1115 "from_entity": {
1116 "type": "string",
1117 "description": "Source entity ID for path operation"
1118 },
1119 "to_entity": {
1120 "type": "string",
1121 "description": "Target entity ID for path operation"
1122 },
1123 "depth": {
1124 "type": "integer",
1125 "description": "Depth of traversal for neighbors/visualize (default: 2)",
1126 "minimum": 1,
1127 "maximum": 4,
1128 "default": 2
1129 },
1130 "format": {
1131 "type": "string",
1132 "description": "Output format for visualize operation",
1133 "enum": ["mermaid", "dot", "ascii"],
1134 "default": "mermaid"
1135 },
1136 "entity_types": {
1137 "type": "array",
1138 "items": {
1139 "type": "string",
1140 "enum": ["Person", "Organization", "Technology", "Concept", "File"]
1141 },
1142 "description": "Filter to specific entity types"
1143 },
1144 "relationship_types": {
1145 "type": "array",
1146 "items": {
1147 "type": "string",
1148 "enum": ["WorksAt", "Created", "Uses", "Implements", "PartOf", "RelatesTo", "MentionedIn", "Supersedes", "ConflictsWith"]
1149 },
1150 "description": "Filter to specific relationship types"
1151 },
1152 "limit": {
1153 "type": "integer",
1154 "description": "Maximum entities to include (default: 50)",
1155 "minimum": 1,
1156 "maximum": 200,
1157 "default": 50
1158 }
1159 },
1160 "required": ["operation"]
1161 }),
1162 }
1163}
1164
1165pub fn init_tool() -> ToolDefinition {
1170 ToolDefinition {
1171 name: "subcog_init".to_string(),
1172 description: "Initialize a Subcog session. Returns compressed XML with namespaces (with counts), domains, tools reference, status, and optional recalled memory previews. Call at session start. Use prompt_understanding tool for full markdown documentation.".to_string(),
1173 input_schema: serde_json::json!({
1174 "type": "object",
1175 "properties": {
1176 "include_recall": {
1177 "type": "boolean",
1178 "description": "Whether to recall project context (default: true)",
1179 "default": true
1180 },
1181 "recall_query": {
1182 "type": "string",
1183 "description": "Custom recall query (default: 'project setup OR architecture OR conventions')"
1184 },
1185 "recall_limit": {
1186 "type": "integer",
1187 "description": "Maximum memories to recall (default: 5)",
1188 "minimum": 1,
1189 "maximum": 20,
1190 "default": 5
1191 }
1192 },
1193 "required": []
1194 }),
1195 }
1196}
1197
1198pub fn templates_tool() -> ToolDefinition {
1206 ToolDefinition {
1207 name: "subcog_templates".to_string(),
1208 description: "Manage context templates for formatting memories. Actions: save, list, get, render, delete.".to_string(),
1209 input_schema: serde_json::json!({
1210 "type": "object",
1211 "properties": {
1212 "action": {
1213 "type": "string",
1214 "description": "Operation to perform",
1215 "enum": ["save", "list", "get", "render", "delete"]
1216 },
1217 "name": {
1218 "type": "string",
1219 "description": "Template name (required for save/get/render/delete)"
1220 },
1221 "content": {
1222 "type": "string",
1223 "description": "Template content with {{variable}} placeholders and {{#each memories}} iteration (for save)"
1224 },
1225 "description": {
1226 "type": "string",
1227 "description": "Human-readable description (for save)"
1228 },
1229 "tags": {
1230 "type": "array",
1231 "items": { "type": "string" },
1232 "description": "Tags for categorization (for save/list)"
1233 },
1234 "domain": {
1235 "type": "string",
1236 "description": "Storage scope: project (default), user, or org",
1237 "enum": ["project", "user", "org"],
1238 "default": "project"
1239 },
1240 "output_format": {
1241 "type": "string",
1242 "description": "Default output format (for save): markdown, json, or xml",
1243 "enum": ["markdown", "json", "xml"],
1244 "default": "markdown"
1245 },
1246 "variables_def": {
1247 "type": "array",
1248 "description": "Variable definitions with metadata (for save)",
1249 "items": {
1250 "type": "object",
1251 "properties": {
1252 "name": { "type": "string" },
1253 "description": { "type": "string" },
1254 "default": { "type": "string" },
1255 "required": { "type": "boolean", "default": true }
1256 },
1257 "required": ["name"]
1258 }
1259 },
1260 "variables": {
1261 "type": "object",
1262 "description": "Custom variable values for rendering (for render)",
1263 "additionalProperties": { "type": "string" }
1264 },
1265 "name_pattern": {
1266 "type": "string",
1267 "description": "Filter by name pattern (for list, glob-style)"
1268 },
1269 "limit": {
1270 "type": "integer",
1271 "description": "Maximum results (for list) or memories (for render)",
1272 "minimum": 1,
1273 "maximum": 100,
1274 "default": 20
1275 },
1276 "version": {
1277 "type": "integer",
1278 "description": "Specific version (for get/render/delete)",
1279 "minimum": 1
1280 },
1281 "query": {
1282 "type": "string",
1283 "description": "Query string for memory search to populate template (for render)"
1284 },
1285 "namespaces": {
1286 "type": "array",
1287 "items": { "type": "string" },
1288 "description": "Namespaces to filter memories (for render)"
1289 },
1290 "format": {
1291 "type": "string",
1292 "description": "Output format override (for render): markdown, json, or xml",
1293 "enum": ["markdown", "json", "xml"]
1294 }
1295 },
1296 "required": ["action"]
1297 }),
1298 }
1299}
1300
1301pub fn context_template_save_tool() -> ToolDefinition {
1303 ToolDefinition {
1304 name: "context_template_save".to_string(),
1305 description: "Save or update a context template for formatting memories. Templates support variable substitution ({{var}}), iteration ({{#each memories}}...{{/each}}), and multiple output formats.".to_string(),
1306 input_schema: serde_json::json!({
1307 "type": "object",
1308 "properties": {
1309 "name": {
1310 "type": "string",
1311 "description": "Template name (unique identifier)"
1312 },
1313 "content": {
1314 "type": "string",
1315 "description": "Template content with variable placeholders. Use {{var}} for variables, {{#each memories}}...{{/each}} for iteration over memories."
1316 },
1317 "description": {
1318 "type": "string",
1319 "description": "Human-readable description of the template's purpose"
1320 },
1321 "tags": {
1322 "type": "array",
1323 "items": { "type": "string" },
1324 "description": "Tags for categorization and filtering"
1325 },
1326 "domain": {
1327 "type": "string",
1328 "description": "Storage scope: project (default), user, or org",
1329 "enum": ["project", "user", "org"],
1330 "default": "project"
1331 },
1332 "output_format": {
1333 "type": "string",
1334 "description": "Default output format: markdown (default), json, or xml",
1335 "enum": ["markdown", "json", "xml"],
1336 "default": "markdown"
1337 },
1338 "variables": {
1339 "type": "array",
1340 "description": "User-defined variable declarations",
1341 "items": {
1342 "type": "object",
1343 "properties": {
1344 "name": {
1345 "type": "string",
1346 "description": "Variable name (used as {{name}} in content)"
1347 },
1348 "description": {
1349 "type": "string",
1350 "description": "Description of what this variable represents"
1351 },
1352 "default": {
1353 "type": "string",
1354 "description": "Default value if not provided at render time"
1355 },
1356 "required": {
1357 "type": "boolean",
1358 "description": "Whether this variable must be provided (default: true)"
1359 }
1360 },
1361 "required": ["name"]
1362 }
1363 }
1364 },
1365 "required": ["name", "content"]
1366 }),
1367 }
1368}
1369
1370pub fn context_template_list_tool() -> ToolDefinition {
1372 ToolDefinition {
1373 name: "context_template_list".to_string(),
1374 description: "List available context templates with optional filtering by domain, tags, or name pattern.".to_string(),
1375 input_schema: serde_json::json!({
1376 "type": "object",
1377 "properties": {
1378 "domain": {
1379 "type": "string",
1380 "description": "Filter by storage scope: project, user, or org",
1381 "enum": ["project", "user", "org"]
1382 },
1383 "tags": {
1384 "type": "array",
1385 "items": { "type": "string" },
1386 "description": "Filter by tags (must have ALL specified tags)"
1387 },
1388 "name_pattern": {
1389 "type": "string",
1390 "description": "Filter by name pattern (substring match)"
1391 },
1392 "limit": {
1393 "type": "integer",
1394 "description": "Maximum number of results (default: 20, max: 100)",
1395 "minimum": 1,
1396 "maximum": 100,
1397 "default": 20
1398 }
1399 },
1400 "required": []
1401 }),
1402 }
1403}
1404
1405pub fn context_template_get_tool() -> ToolDefinition {
1407 ToolDefinition {
1408 name: "context_template_get".to_string(),
1409 description: "Get a context template by name, optionally specifying version and domain."
1410 .to_string(),
1411 input_schema: serde_json::json!({
1412 "type": "object",
1413 "properties": {
1414 "name": {
1415 "type": "string",
1416 "description": "Template name to retrieve"
1417 },
1418 "version": {
1419 "type": "integer",
1420 "description": "Specific version to retrieve (default: latest)",
1421 "minimum": 1
1422 },
1423 "domain": {
1424 "type": "string",
1425 "description": "Storage scope to search: project, user, or org",
1426 "enum": ["project", "user", "org"]
1427 }
1428 },
1429 "required": ["name"]
1430 }),
1431 }
1432}
1433
1434pub fn context_template_render_tool() -> ToolDefinition {
1436 ToolDefinition {
1437 name: "context_template_render".to_string(),
1438 description: "Render a context template with memories from a search query. Combines template rendering with memory recall for formatted output.".to_string(),
1439 input_schema: serde_json::json!({
1440 "type": "object",
1441 "properties": {
1442 "name": {
1443 "type": "string",
1444 "description": "Template name to render"
1445 },
1446 "version": {
1447 "type": "integer",
1448 "description": "Specific template version (default: latest)",
1449 "minimum": 1
1450 },
1451 "query": {
1452 "type": "string",
1453 "description": "Search query to find memories for the template"
1454 },
1455 "namespaces": {
1456 "type": "array",
1457 "items": {
1458 "type": "string",
1459 "enum": ["decisions", "patterns", "learnings", "context", "tech-debt", "apis", "config", "security", "performance", "testing"]
1460 },
1461 "description": "Filter memories by namespaces"
1462 },
1463 "limit": {
1464 "type": "integer",
1465 "description": "Maximum memories to include (default: 10)",
1466 "minimum": 1,
1467 "maximum": 50,
1468 "default": 10
1469 },
1470 "format": {
1471 "type": "string",
1472 "description": "Override output format: markdown, json, or xml",
1473 "enum": ["markdown", "json", "xml"]
1474 },
1475 "variables": {
1476 "type": "object",
1477 "description": "Custom variable values as key-value pairs",
1478 "additionalProperties": { "type": "string" }
1479 }
1480 },
1481 "required": ["name"]
1482 }),
1483 }
1484}
1485
1486pub fn context_template_delete_tool() -> ToolDefinition {
1488 ToolDefinition {
1489 name: "context_template_delete".to_string(),
1490 description: "Delete a context template. Can delete a specific version or all versions."
1491 .to_string(),
1492 input_schema: serde_json::json!({
1493 "type": "object",
1494 "properties": {
1495 "name": {
1496 "type": "string",
1497 "description": "Template name to delete"
1498 },
1499 "version": {
1500 "type": "integer",
1501 "description": "Specific version to delete (omit to delete all versions)",
1502 "minimum": 1
1503 },
1504 "domain": {
1505 "type": "string",
1506 "description": "Storage scope: project (default), user, or org",
1507 "enum": ["project", "user", "org"],
1508 "default": "project"
1509 }
1510 },
1511 "required": ["name", "domain"]
1512 }),
1513 }
1514}
1515
1516#[cfg(feature = "group-scope")]
1522pub fn group_create_tool() -> super::ToolDefinition {
1523 super::ToolDefinition {
1524 name: "subcog_group_create".to_string(),
1525 description:
1526 "Create a new group for shared memory access. You become the admin of the group."
1527 .to_string(),
1528 input_schema: serde_json::json!({
1529 "type": "object",
1530 "properties": {
1531 "name": {
1532 "type": "string",
1533 "description": "Group name (must be unique)"
1534 },
1535 "description": {
1536 "type": "string",
1537 "description": "Optional description of the group's purpose"
1538 }
1539 },
1540 "required": ["name"]
1541 }),
1542 }
1543}
1544
1545#[cfg(feature = "group-scope")]
1547pub fn group_list_tool() -> super::ToolDefinition {
1548 super::ToolDefinition {
1549 name: "subcog_group_list".to_string(),
1550 description: "List all groups you have access to, including your role in each.".to_string(),
1551 input_schema: serde_json::json!({
1552 "type": "object",
1553 "properties": {},
1554 "required": []
1555 }),
1556 }
1557}
1558
1559#[cfg(feature = "group-scope")]
1561pub fn group_get_tool() -> super::ToolDefinition {
1562 super::ToolDefinition {
1563 name: "subcog_group_get".to_string(),
1564 description: "Get details of a specific group, including members and their roles."
1565 .to_string(),
1566 input_schema: serde_json::json!({
1567 "type": "object",
1568 "properties": {
1569 "group_id": {
1570 "type": "string",
1571 "description": "The ID of the group to retrieve"
1572 }
1573 },
1574 "required": ["group_id"]
1575 }),
1576 }
1577}
1578
1579#[cfg(feature = "group-scope")]
1581pub fn group_add_member_tool() -> super::ToolDefinition {
1582 super::ToolDefinition {
1583 name: "subcog_group_add_member".to_string(),
1584 description:
1585 "Add a member to a group with a specified role. Requires admin role in the group."
1586 .to_string(),
1587 input_schema: serde_json::json!({
1588 "type": "object",
1589 "properties": {
1590 "group_id": {
1591 "type": "string",
1592 "description": "The ID of the group"
1593 },
1594 "user_id": {
1595 "type": "string",
1596 "description": "The user ID to add"
1597 },
1598 "role": {
1599 "type": "string",
1600 "description": "Role for the new member",
1601 "enum": ["read", "write", "admin"],
1602 "default": "read"
1603 }
1604 },
1605 "required": ["group_id", "user_id"]
1606 }),
1607 }
1608}
1609
1610#[cfg(feature = "group-scope")]
1612pub fn group_remove_member_tool() -> super::ToolDefinition {
1613 super::ToolDefinition {
1614 name: "subcog_group_remove_member".to_string(),
1615 description: "Remove a member from a group. Requires admin role in the group.".to_string(),
1616 input_schema: serde_json::json!({
1617 "type": "object",
1618 "properties": {
1619 "group_id": {
1620 "type": "string",
1621 "description": "The ID of the group"
1622 },
1623 "user_id": {
1624 "type": "string",
1625 "description": "The user ID to remove"
1626 }
1627 },
1628 "required": ["group_id", "user_id"]
1629 }),
1630 }
1631}
1632
1633#[cfg(feature = "group-scope")]
1635pub fn group_update_role_tool() -> super::ToolDefinition {
1636 super::ToolDefinition {
1637 name: "subcog_group_update_role".to_string(),
1638 description: "Update a member's role in a group. Requires admin role in the group."
1639 .to_string(),
1640 input_schema: serde_json::json!({
1641 "type": "object",
1642 "properties": {
1643 "group_id": {
1644 "type": "string",
1645 "description": "The ID of the group"
1646 },
1647 "user_id": {
1648 "type": "string",
1649 "description": "The user ID to update"
1650 },
1651 "role": {
1652 "type": "string",
1653 "description": "New role for the member",
1654 "enum": ["read", "write", "admin"]
1655 }
1656 },
1657 "required": ["group_id", "user_id", "role"]
1658 }),
1659 }
1660}
1661
1662#[cfg(feature = "group-scope")]
1664pub fn group_delete_tool() -> super::ToolDefinition {
1665 super::ToolDefinition {
1666 name: "subcog_group_delete".to_string(),
1667 description: "Delete a group. Requires admin role. Warning: This does not delete memories, but they will no longer be group-accessible.".to_string(),
1668 input_schema: serde_json::json!({
1669 "type": "object",
1670 "properties": {
1671 "group_id": {
1672 "type": "string",
1673 "description": "The ID of the group to delete"
1674 }
1675 },
1676 "required": ["group_id"]
1677 }),
1678 }
1679}
1680
1681#[cfg(feature = "group-scope")]
1685pub fn groups_tool() -> super::ToolDefinition {
1686 super::ToolDefinition {
1687 name: "subcog_groups".to_string(),
1688 description: "Manage groups for shared memory access. Actions: create, list, get, add_member, remove_member, update_role, delete.".to_string(),
1689 input_schema: serde_json::json!({
1690 "type": "object",
1691 "properties": {
1692 "action": {
1693 "type": "string",
1694 "description": "Operation to perform",
1695 "enum": ["create", "list", "get", "add_member", "remove_member", "update_role", "delete"]
1696 },
1697 "group_id": {
1698 "type": "string",
1699 "description": "Group ID (required for get/add_member/remove_member/update_role/delete)"
1700 },
1701 "name": {
1702 "type": "string",
1703 "description": "Group name (required for create)"
1704 },
1705 "description": {
1706 "type": "string",
1707 "description": "Group description (for create)"
1708 },
1709 "user_id": {
1710 "type": "string",
1711 "description": "User ID to add/remove/update (for add_member/remove_member/update_role)"
1712 },
1713 "role": {
1714 "type": "string",
1715 "description": "Role for the member (for add_member/update_role)",
1716 "enum": ["read", "write", "admin"],
1717 "default": "read"
1718 }
1719 },
1720 "required": ["action"]
1721 }),
1722 }
1723}