cognee 0.2.3.dev1__py3-none-any.whl → 0.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognee/__main__.py +4 -0
- cognee/api/v1/add/add.py +18 -6
- cognee/api/v1/cognify/code_graph_pipeline.py +7 -1
- cognee/api/v1/cognify/cognify.py +22 -107
- cognee/api/v1/cognify/routers/get_cognify_router.py +11 -3
- cognee/api/v1/datasets/routers/get_datasets_router.py +1 -1
- cognee/api/v1/responses/default_tools.py +4 -0
- cognee/api/v1/responses/dispatch_function.py +6 -1
- cognee/api/v1/responses/models.py +1 -1
- cognee/api/v1/search/search.py +6 -0
- cognee/cli/__init__.py +10 -0
- cognee/cli/_cognee.py +180 -0
- cognee/cli/commands/__init__.py +1 -0
- cognee/cli/commands/add_command.py +80 -0
- cognee/cli/commands/cognify_command.py +128 -0
- cognee/cli/commands/config_command.py +225 -0
- cognee/cli/commands/delete_command.py +80 -0
- cognee/cli/commands/search_command.py +149 -0
- cognee/cli/config.py +33 -0
- cognee/cli/debug.py +21 -0
- cognee/cli/echo.py +45 -0
- cognee/cli/exceptions.py +23 -0
- cognee/cli/minimal_cli.py +97 -0
- cognee/cli/reference.py +26 -0
- cognee/cli/suppress_logging.py +12 -0
- cognee/eval_framework/corpus_builder/corpus_builder_executor.py +2 -2
- cognee/eval_framework/eval_config.py +1 -1
- cognee/infrastructure/databases/graph/get_graph_engine.py +4 -9
- cognee/infrastructure/databases/graph/kuzu/adapter.py +64 -2
- cognee/infrastructure/databases/graph/neo4j_driver/adapter.py +49 -0
- cognee/infrastructure/databases/vector/embeddings/FastembedEmbeddingEngine.py +5 -3
- cognee/infrastructure/databases/vector/embeddings/LiteLLMEmbeddingEngine.py +16 -7
- cognee/infrastructure/databases/vector/embeddings/OllamaEmbeddingEngine.py +5 -5
- cognee/infrastructure/databases/vector/embeddings/config.py +2 -2
- cognee/infrastructure/databases/vector/embeddings/get_embedding_engine.py +6 -6
- cognee/infrastructure/files/utils/get_data_file_path.py +14 -9
- cognee/infrastructure/files/utils/get_file_metadata.py +2 -1
- cognee/infrastructure/llm/LLMGateway.py +14 -5
- cognee/infrastructure/llm/config.py +5 -5
- cognee/infrastructure/llm/structured_output_framework/baml/baml_src/extraction/knowledge_graph/extract_content_graph.py +16 -5
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/extraction/knowledge_graph/extract_content_graph.py +19 -15
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/anthropic/adapter.py +3 -3
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/gemini/adapter.py +3 -3
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/generic_llm_api/adapter.py +2 -2
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/get_llm_client.py +14 -8
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/ollama/adapter.py +6 -4
- cognee/infrastructure/llm/structured_output_framework/litellm_instructor/llm/openai/adapter.py +3 -3
- cognee/infrastructure/llm/tokenizer/Gemini/adapter.py +2 -2
- cognee/infrastructure/llm/tokenizer/HuggingFace/adapter.py +3 -3
- cognee/infrastructure/llm/tokenizer/Mistral/adapter.py +3 -3
- cognee/infrastructure/llm/tokenizer/TikToken/adapter.py +6 -6
- cognee/infrastructure/llm/utils.py +7 -7
- cognee/modules/data/methods/__init__.py +2 -0
- cognee/modules/data/methods/create_authorized_dataset.py +19 -0
- cognee/modules/data/methods/get_authorized_dataset.py +11 -5
- cognee/modules/data/methods/get_authorized_dataset_by_name.py +16 -0
- cognee/modules/data/methods/load_or_create_datasets.py +2 -20
- cognee/modules/graph/methods/get_formatted_graph_data.py +3 -2
- cognee/modules/pipelines/__init__.py +1 -1
- cognee/modules/pipelines/exceptions/tasks.py +18 -0
- cognee/modules/pipelines/layers/__init__.py +1 -0
- cognee/modules/pipelines/layers/check_pipeline_run_qualification.py +59 -0
- cognee/modules/pipelines/layers/pipeline_execution_mode.py +127 -0
- cognee/modules/pipelines/layers/reset_dataset_pipeline_run_status.py +12 -0
- cognee/modules/pipelines/layers/resolve_authorized_user_dataset.py +34 -0
- cognee/modules/pipelines/layers/resolve_authorized_user_datasets.py +55 -0
- cognee/modules/pipelines/layers/setup_and_check_environment.py +41 -0
- cognee/modules/pipelines/layers/validate_pipeline_tasks.py +20 -0
- cognee/modules/pipelines/methods/__init__.py +2 -0
- cognee/modules/pipelines/methods/get_pipeline_runs_by_dataset.py +34 -0
- cognee/modules/pipelines/methods/reset_pipeline_run_status.py +16 -0
- cognee/modules/pipelines/operations/__init__.py +0 -1
- cognee/modules/pipelines/operations/log_pipeline_run_initiated.py +1 -1
- cognee/modules/pipelines/operations/pipeline.py +23 -138
- cognee/modules/retrieval/base_feedback.py +11 -0
- cognee/modules/retrieval/cypher_search_retriever.py +1 -9
- cognee/modules/retrieval/graph_completion_context_extension_retriever.py +9 -2
- cognee/modules/retrieval/graph_completion_cot_retriever.py +13 -6
- cognee/modules/retrieval/graph_completion_retriever.py +89 -5
- cognee/modules/retrieval/graph_summary_completion_retriever.py +2 -0
- cognee/modules/retrieval/natural_language_retriever.py +0 -4
- cognee/modules/retrieval/user_qa_feedback.py +83 -0
- cognee/modules/retrieval/utils/extract_uuid_from_node.py +18 -0
- cognee/modules/retrieval/utils/models.py +40 -0
- cognee/modules/search/methods/search.py +46 -5
- cognee/modules/search/types/SearchType.py +1 -0
- cognee/modules/settings/get_settings.py +2 -2
- cognee/shared/CodeGraphEntities.py +1 -0
- cognee/shared/logging_utils.py +142 -31
- cognee/shared/utils.py +0 -1
- cognee/tasks/graph/extract_graph_from_data.py +6 -2
- cognee/tasks/repo_processor/get_local_dependencies.py +2 -0
- cognee/tasks/repo_processor/get_repo_file_dependencies.py +120 -48
- cognee/tasks/storage/add_data_points.py +33 -3
- cognee/tests/integration/cli/__init__.py +3 -0
- cognee/tests/integration/cli/test_cli_integration.py +331 -0
- cognee/tests/integration/documents/PdfDocument_test.py +2 -2
- cognee/tests/integration/documents/TextDocument_test.py +2 -4
- cognee/tests/integration/documents/UnstructuredDocument_test.py +5 -8
- cognee/tests/{test_deletion.py → test_delete_hard.py} +0 -37
- cognee/tests/test_delete_soft.py +85 -0
- cognee/tests/test_kuzu.py +2 -2
- cognee/tests/test_neo4j.py +2 -2
- cognee/tests/test_search_db.py +126 -7
- cognee/tests/unit/cli/__init__.py +3 -0
- cognee/tests/unit/cli/test_cli_commands.py +483 -0
- cognee/tests/unit/cli/test_cli_edge_cases.py +625 -0
- cognee/tests/unit/cli/test_cli_main.py +173 -0
- cognee/tests/unit/cli/test_cli_runner.py +62 -0
- cognee/tests/unit/cli/test_cli_utils.py +127 -0
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_context_extension_test.py +3 -3
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py +3 -3
- cognee/tests/unit/modules/retrieval/graph_completion_retriever_test.py +3 -3
- cognee/tests/unit/modules/search/search_methods_test.py +2 -0
- {cognee-0.2.3.dev1.dist-info → cognee-0.2.4.dist-info}/METADATA +7 -5
- {cognee-0.2.3.dev1.dist-info → cognee-0.2.4.dist-info}/RECORD +120 -83
- cognee-0.2.4.dist-info/entry_points.txt +2 -0
- cognee/infrastructure/databases/graph/networkx/__init__.py +0 -0
- cognee/infrastructure/databases/graph/networkx/adapter.py +0 -1017
- cognee/infrastructure/pipeline/models/Operation.py +0 -60
- cognee/infrastructure/pipeline/models/__init__.py +0 -0
- cognee/notebooks/github_analysis_step_by_step.ipynb +0 -37
- cognee/tests/tasks/descriptive_metrics/networkx_metrics_test.py +0 -7
- {cognee-0.2.3.dev1.dist-info → cognee-0.2.4.dist-info}/WHEEL +0 -0
- {cognee-0.2.3.dev1.dist-info → cognee-0.2.4.dist-info}/licenses/LICENSE +0 -0
- {cognee-0.2.3.dev1.dist-info → cognee-0.2.4.dist-info}/licenses/NOTICE.md +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from cognee.cli.reference import SupportsCliCommand
|
|
6
|
+
from cognee.cli import DEFAULT_DOCS_URL
|
|
7
|
+
from cognee.cli.config import CHUNKER_CHOICES
|
|
8
|
+
import cognee.cli.echo as fmt
|
|
9
|
+
from cognee.cli.exceptions import CliCommandException, CliCommandInnerException
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CognifyCommand(SupportsCliCommand):
|
|
13
|
+
command_string = "cognify"
|
|
14
|
+
help_string = "Transform ingested data into a structured knowledge graph"
|
|
15
|
+
docs_url = DEFAULT_DOCS_URL
|
|
16
|
+
description = """
|
|
17
|
+
Transform ingested data into a structured knowledge graph.
|
|
18
|
+
|
|
19
|
+
This is the core processing step in Cognee that converts raw text and documents
|
|
20
|
+
into an intelligent knowledge graph. It analyzes content, extracts entities and
|
|
21
|
+
relationships, and creates semantic connections for enhanced search and reasoning.
|
|
22
|
+
|
|
23
|
+
Processing Pipeline:
|
|
24
|
+
1. **Document Classification**: Identifies document types and structures
|
|
25
|
+
2. **Permission Validation**: Ensures user has processing rights
|
|
26
|
+
3. **Text Chunking**: Breaks content into semantically meaningful segments
|
|
27
|
+
4. **Entity Extraction**: Identifies key concepts, people, places, organizations
|
|
28
|
+
5. **Relationship Detection**: Discovers connections between entities
|
|
29
|
+
6. **Graph Construction**: Builds semantic knowledge graph with embeddings
|
|
30
|
+
7. **Content Summarization**: Creates hierarchical summaries for navigation
|
|
31
|
+
|
|
32
|
+
After successful cognify processing, use `cognee search` to query the knowledge graph.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
36
|
+
parser.add_argument(
|
|
37
|
+
"--datasets",
|
|
38
|
+
"-d",
|
|
39
|
+
nargs="*",
|
|
40
|
+
help="Dataset name(s) to process. Processes all available data if not specified. Can be multiple: --datasets dataset1 dataset2",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--chunk-size",
|
|
44
|
+
type=int,
|
|
45
|
+
help="Maximum tokens per chunk. Auto-calculated based on LLM if not specified (~512-8192 tokens)",
|
|
46
|
+
)
|
|
47
|
+
parser.add_argument(
|
|
48
|
+
"--ontology-file", help="Path to RDF/OWL ontology file for domain-specific entity types"
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--chunker",
|
|
52
|
+
choices=CHUNKER_CHOICES,
|
|
53
|
+
default="TextChunker",
|
|
54
|
+
help="Text chunking strategy (default: TextChunker)",
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--background",
|
|
58
|
+
"-b",
|
|
59
|
+
action="store_true",
|
|
60
|
+
help="Run processing in background and return immediately (recommended for large datasets)",
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--verbose", "-v", action="store_true", help="Show detailed progress information"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def execute(self, args: argparse.Namespace) -> None:
|
|
67
|
+
try:
|
|
68
|
+
# Import cognee here to avoid circular imports
|
|
69
|
+
import cognee
|
|
70
|
+
|
|
71
|
+
# Prepare datasets parameter
|
|
72
|
+
datasets = args.datasets if args.datasets else None
|
|
73
|
+
dataset_msg = f" for datasets {datasets}" if datasets else " for all available data"
|
|
74
|
+
fmt.echo(f"Starting cognification{dataset_msg}...")
|
|
75
|
+
|
|
76
|
+
if args.verbose:
|
|
77
|
+
fmt.note("This process will analyze your data and build knowledge graphs.")
|
|
78
|
+
fmt.note("Depending on data size, this may take several minutes.")
|
|
79
|
+
if args.background:
|
|
80
|
+
fmt.note(
|
|
81
|
+
"Running in background mode - the process will continue after this command exits."
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Prepare chunker parameter - will be handled in the async function
|
|
85
|
+
|
|
86
|
+
# Run the async cognify function
|
|
87
|
+
async def run_cognify():
|
|
88
|
+
try:
|
|
89
|
+
# Import chunker classes here
|
|
90
|
+
from cognee.modules.chunking.TextChunker import TextChunker
|
|
91
|
+
|
|
92
|
+
chunker_class = TextChunker # Default
|
|
93
|
+
if args.chunker == "LangchainChunker":
|
|
94
|
+
try:
|
|
95
|
+
from cognee.modules.chunking.LangchainChunker import LangchainChunker
|
|
96
|
+
|
|
97
|
+
chunker_class = LangchainChunker
|
|
98
|
+
except ImportError:
|
|
99
|
+
fmt.warning("LangchainChunker not available, using TextChunker")
|
|
100
|
+
|
|
101
|
+
result = await cognee.cognify(
|
|
102
|
+
datasets=datasets,
|
|
103
|
+
chunker=chunker_class,
|
|
104
|
+
chunk_size=args.chunk_size,
|
|
105
|
+
ontology_file_path=args.ontology_file,
|
|
106
|
+
run_in_background=args.background,
|
|
107
|
+
)
|
|
108
|
+
return result
|
|
109
|
+
except Exception as e:
|
|
110
|
+
raise CliCommandInnerException(f"Failed to cognify: {str(e)}")
|
|
111
|
+
|
|
112
|
+
result = asyncio.run(run_cognify())
|
|
113
|
+
|
|
114
|
+
if args.background:
|
|
115
|
+
fmt.success("Cognification started in background!")
|
|
116
|
+
if args.verbose and result:
|
|
117
|
+
fmt.echo(
|
|
118
|
+
"Background processing initiated. Use pipeline monitoring to track progress."
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
fmt.success("Cognification completed successfully!")
|
|
122
|
+
if args.verbose and result:
|
|
123
|
+
fmt.echo(f"Processing results: {result}")
|
|
124
|
+
|
|
125
|
+
except Exception as e:
|
|
126
|
+
if isinstance(e, CliCommandInnerException):
|
|
127
|
+
raise CliCommandException(str(e), error_code=1)
|
|
128
|
+
raise CliCommandException(f"Error during cognification: {str(e)}", error_code=1)
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
from typing import Optional, Any
|
|
4
|
+
|
|
5
|
+
from cognee.cli.reference import SupportsCliCommand
|
|
6
|
+
from cognee.cli import DEFAULT_DOCS_URL
|
|
7
|
+
import cognee.cli.echo as fmt
|
|
8
|
+
from cognee.cli.exceptions import CliCommandException, CliCommandInnerException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConfigCommand(SupportsCliCommand):
|
|
12
|
+
command_string = "config"
|
|
13
|
+
help_string = "Manage cognee configuration settings"
|
|
14
|
+
docs_url = DEFAULT_DOCS_URL
|
|
15
|
+
description = """
|
|
16
|
+
The `cognee config` command allows you to view and modify configuration settings.
|
|
17
|
+
|
|
18
|
+
You can:
|
|
19
|
+
- View all current configuration settings
|
|
20
|
+
- Get specific configuration values
|
|
21
|
+
- Set configuration values
|
|
22
|
+
- Unset (reset to default) specific configuration values
|
|
23
|
+
- Reset all configuration to defaults
|
|
24
|
+
|
|
25
|
+
Configuration changes will affect how cognee processes and stores data.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
29
|
+
subparsers = parser.add_subparsers(dest="config_action", help="Configuration actions")
|
|
30
|
+
|
|
31
|
+
# Get command
|
|
32
|
+
get_parser = subparsers.add_parser("get", help="Get configuration value(s)")
|
|
33
|
+
get_parser.add_argument(
|
|
34
|
+
"key", nargs="?", help="Configuration key to retrieve (shows all if not specified)"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Set command
|
|
38
|
+
set_parser = subparsers.add_parser("set", help="Set configuration value")
|
|
39
|
+
set_parser.add_argument("key", help="Configuration key to set")
|
|
40
|
+
set_parser.add_argument("value", help="Configuration value to set")
|
|
41
|
+
|
|
42
|
+
# List command
|
|
43
|
+
subparsers.add_parser("list", help="List all configuration keys")
|
|
44
|
+
|
|
45
|
+
# Unset command
|
|
46
|
+
unset_parser = subparsers.add_parser("unset", help="Remove/unset a configuration value")
|
|
47
|
+
unset_parser.add_argument("key", help="Configuration key to unset")
|
|
48
|
+
unset_parser.add_argument(
|
|
49
|
+
"--force", "-f", action="store_true", help="Skip confirmation prompt"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Reset command
|
|
53
|
+
reset_parser = subparsers.add_parser("reset", help="Reset configuration to defaults")
|
|
54
|
+
reset_parser.add_argument(
|
|
55
|
+
"--force", "-f", action="store_true", help="Skip confirmation prompt"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def execute(self, args: argparse.Namespace) -> None:
|
|
59
|
+
try:
|
|
60
|
+
# Import cognee here to avoid circular imports
|
|
61
|
+
import cognee
|
|
62
|
+
|
|
63
|
+
if not hasattr(args, "config_action") or args.config_action is None:
|
|
64
|
+
fmt.error("Please specify a config action: get, set, unset, list, or reset")
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
if args.config_action == "get":
|
|
68
|
+
self._handle_get(args)
|
|
69
|
+
elif args.config_action == "set":
|
|
70
|
+
self._handle_set(args)
|
|
71
|
+
elif args.config_action == "unset":
|
|
72
|
+
self._handle_unset(args)
|
|
73
|
+
elif args.config_action == "list":
|
|
74
|
+
self._handle_list(args)
|
|
75
|
+
elif args.config_action == "reset":
|
|
76
|
+
self._handle_reset(args)
|
|
77
|
+
else:
|
|
78
|
+
fmt.error(f"Unknown config action: {args.config_action}")
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
if isinstance(e, CliCommandInnerException):
|
|
82
|
+
raise CliCommandException(str(e), error_code=1)
|
|
83
|
+
raise CliCommandException(f"Error managing configuration: {str(e)}", error_code=1)
|
|
84
|
+
|
|
85
|
+
def _handle_get(self, args: argparse.Namespace) -> None:
|
|
86
|
+
try:
|
|
87
|
+
import cognee
|
|
88
|
+
|
|
89
|
+
if args.key:
|
|
90
|
+
# Get specific key
|
|
91
|
+
try:
|
|
92
|
+
if hasattr(cognee.config, "get"):
|
|
93
|
+
value = cognee.config.get(args.key)
|
|
94
|
+
fmt.echo(f"{args.key}: {value}")
|
|
95
|
+
else:
|
|
96
|
+
fmt.error("Configuration retrieval not implemented yet")
|
|
97
|
+
fmt.note(
|
|
98
|
+
"The config system currently only supports setting values, not retrieving them"
|
|
99
|
+
)
|
|
100
|
+
fmt.note(f"To set this value: 'cognee config set {args.key} <value>'")
|
|
101
|
+
except Exception:
|
|
102
|
+
fmt.error(f"Configuration key '{args.key}' not found or retrieval failed")
|
|
103
|
+
else:
|
|
104
|
+
# Get all configuration
|
|
105
|
+
try:
|
|
106
|
+
if hasattr(cognee.config, "get_all"):
|
|
107
|
+
config_dict = cognee.config.get_all()
|
|
108
|
+
if config_dict:
|
|
109
|
+
fmt.echo("Current configuration:")
|
|
110
|
+
for key, value in config_dict.items():
|
|
111
|
+
fmt.echo(f" {key}: {value}")
|
|
112
|
+
else:
|
|
113
|
+
fmt.echo("No configuration settings found")
|
|
114
|
+
else:
|
|
115
|
+
fmt.error("Configuration viewing not implemented yet")
|
|
116
|
+
fmt.note(
|
|
117
|
+
"The config system currently only supports setting values, not retrieving them"
|
|
118
|
+
)
|
|
119
|
+
fmt.note("Available commands: 'cognee config set <key> <value>'")
|
|
120
|
+
except Exception:
|
|
121
|
+
fmt.error("Failed to retrieve configuration")
|
|
122
|
+
fmt.note("Configuration viewing not fully implemented yet")
|
|
123
|
+
|
|
124
|
+
except Exception as e:
|
|
125
|
+
raise CliCommandInnerException(f"Failed to get configuration: {str(e)}")
|
|
126
|
+
|
|
127
|
+
def _handle_set(self, args: argparse.Namespace) -> None:
|
|
128
|
+
try:
|
|
129
|
+
import cognee
|
|
130
|
+
|
|
131
|
+
# Try to parse value as JSON, otherwise treat as string
|
|
132
|
+
try:
|
|
133
|
+
value = json.loads(args.value)
|
|
134
|
+
except json.JSONDecodeError:
|
|
135
|
+
value = args.value
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
cognee.config.set(args.key, value)
|
|
139
|
+
fmt.success(f"Set {args.key} = {value}")
|
|
140
|
+
except Exception:
|
|
141
|
+
fmt.error(f"Failed to set configuration key '{args.key}'")
|
|
142
|
+
|
|
143
|
+
except Exception as e:
|
|
144
|
+
raise CliCommandInnerException(f"Failed to set configuration: {str(e)}")
|
|
145
|
+
|
|
146
|
+
def _handle_unset(self, args: argparse.Namespace) -> None:
|
|
147
|
+
try:
|
|
148
|
+
import cognee
|
|
149
|
+
|
|
150
|
+
# Confirm unset unless forced
|
|
151
|
+
if not args.force:
|
|
152
|
+
if not fmt.confirm(f"Unset configuration key '{args.key}'?"):
|
|
153
|
+
fmt.echo("Unset cancelled.")
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
# Since the config system doesn't have explicit unset methods,
|
|
157
|
+
# we need to map config keys to their reset/default behaviors
|
|
158
|
+
config_key_mappings = {
|
|
159
|
+
# LLM configuration
|
|
160
|
+
"llm_provider": ("set_llm_provider", "openai"),
|
|
161
|
+
"llm_model": ("set_llm_model", "gpt-5-mini"),
|
|
162
|
+
"llm_api_key": ("set_llm_api_key", ""),
|
|
163
|
+
"llm_endpoint": ("set_llm_endpoint", ""),
|
|
164
|
+
# Database configuration
|
|
165
|
+
"graph_database_provider": ("set_graph_database_provider", "kuzu"),
|
|
166
|
+
"vector_db_provider": ("set_vector_db_provider", "lancedb"),
|
|
167
|
+
"vector_db_url": ("set_vector_db_url", ""),
|
|
168
|
+
"vector_db_key": ("set_vector_db_key", ""),
|
|
169
|
+
# Chunking configuration
|
|
170
|
+
"chunk_size": ("set_chunk_size", 1500),
|
|
171
|
+
"chunk_overlap": ("set_chunk_overlap", 10),
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if args.key in config_key_mappings:
|
|
175
|
+
method_name, default_value = config_key_mappings[args.key]
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
# Get the method and call it with the default value
|
|
179
|
+
method = getattr(cognee.config, method_name)
|
|
180
|
+
method(default_value)
|
|
181
|
+
fmt.success(f"Unset {args.key} (reset to default: {default_value})")
|
|
182
|
+
except AttributeError:
|
|
183
|
+
fmt.error(f"Configuration method '{method_name}' not found")
|
|
184
|
+
except Exception as e:
|
|
185
|
+
fmt.error(f"Failed to unset '{args.key}': {str(e)}")
|
|
186
|
+
else:
|
|
187
|
+
fmt.error(f"Unknown configuration key '{args.key}'")
|
|
188
|
+
fmt.note("Available keys: " + ", ".join(config_key_mappings.keys()))
|
|
189
|
+
fmt.note("Use 'cognee config list' to see all available configuration options")
|
|
190
|
+
|
|
191
|
+
except Exception as e:
|
|
192
|
+
raise CliCommandInnerException(f"Failed to unset configuration: {str(e)}")
|
|
193
|
+
|
|
194
|
+
def _handle_list(self, args: argparse.Namespace) -> None:
|
|
195
|
+
try:
|
|
196
|
+
import cognee
|
|
197
|
+
|
|
198
|
+
# This would need to be implemented in cognee.config
|
|
199
|
+
fmt.note("Available configuration keys:")
|
|
200
|
+
fmt.echo(" llm_provider, llm_model, llm_api_key, llm_endpoint")
|
|
201
|
+
fmt.echo(" graph_database_provider, vector_db_provider")
|
|
202
|
+
fmt.echo(" vector_db_url, vector_db_key")
|
|
203
|
+
fmt.echo(" chunk_size, chunk_overlap")
|
|
204
|
+
fmt.echo("")
|
|
205
|
+
fmt.echo("Commands:")
|
|
206
|
+
fmt.echo(" cognee config get [key] - View configuration")
|
|
207
|
+
fmt.echo(" cognee config set <key> <value> - Set configuration")
|
|
208
|
+
fmt.echo(" cognee config unset <key> - Reset key to default")
|
|
209
|
+
fmt.echo(" cognee config reset - Reset all to defaults")
|
|
210
|
+
|
|
211
|
+
except Exception as e:
|
|
212
|
+
raise CliCommandInnerException(f"Failed to list configuration: {str(e)}")
|
|
213
|
+
|
|
214
|
+
def _handle_reset(self, args: argparse.Namespace) -> None:
|
|
215
|
+
try:
|
|
216
|
+
if not args.force:
|
|
217
|
+
if not fmt.confirm("Reset all configuration to defaults?"):
|
|
218
|
+
fmt.echo("Reset cancelled.")
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
fmt.note("Configuration reset not fully implemented yet")
|
|
222
|
+
fmt.echo("This would reset all settings to their default values")
|
|
223
|
+
|
|
224
|
+
except Exception as e:
|
|
225
|
+
raise CliCommandInnerException(f"Failed to reset configuration: {str(e)}")
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from cognee.cli.reference import SupportsCliCommand
|
|
6
|
+
from cognee.cli import DEFAULT_DOCS_URL
|
|
7
|
+
import cognee.cli.echo as fmt
|
|
8
|
+
from cognee.cli.exceptions import CliCommandException, CliCommandInnerException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DeleteCommand(SupportsCliCommand):
|
|
12
|
+
command_string = "delete"
|
|
13
|
+
help_string = "Delete data from cognee knowledge base"
|
|
14
|
+
docs_url = DEFAULT_DOCS_URL
|
|
15
|
+
description = """
|
|
16
|
+
The `cognee delete` command removes data from your knowledge base.
|
|
17
|
+
|
|
18
|
+
You can delete:
|
|
19
|
+
- Specific datasets by name
|
|
20
|
+
- All data (with confirmation)
|
|
21
|
+
- Data for specific users
|
|
22
|
+
|
|
23
|
+
Be careful with deletion operations as they are irreversible.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
27
|
+
parser.add_argument("--dataset-name", "-d", help="Specific dataset to delete")
|
|
28
|
+
parser.add_argument("--user-id", "-u", help="User ID to delete data for")
|
|
29
|
+
parser.add_argument(
|
|
30
|
+
"--all", action="store_true", help="Delete all data (requires confirmation)"
|
|
31
|
+
)
|
|
32
|
+
parser.add_argument("--force", "-f", action="store_true", help="Skip confirmation prompts")
|
|
33
|
+
|
|
34
|
+
def execute(self, args: argparse.Namespace) -> None:
|
|
35
|
+
try:
|
|
36
|
+
# Import cognee here to avoid circular imports
|
|
37
|
+
import cognee
|
|
38
|
+
|
|
39
|
+
# Validate arguments
|
|
40
|
+
if not any([args.dataset_name, args.user_id, args.all]):
|
|
41
|
+
fmt.error("Please specify what to delete: --dataset-name, --user-id, or --all")
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
# Build confirmation message
|
|
45
|
+
if args.all:
|
|
46
|
+
confirm_msg = "Delete ALL data from cognee?"
|
|
47
|
+
operation = "all data"
|
|
48
|
+
elif args.dataset_name:
|
|
49
|
+
confirm_msg = f"Delete dataset '{args.dataset_name}'?"
|
|
50
|
+
operation = f"dataset '{args.dataset_name}'"
|
|
51
|
+
elif args.user_id:
|
|
52
|
+
confirm_msg = f"Delete all data for user '{args.user_id}'?"
|
|
53
|
+
operation = f"data for user '{args.user_id}'"
|
|
54
|
+
|
|
55
|
+
# Confirm deletion unless forced
|
|
56
|
+
if not args.force:
|
|
57
|
+
fmt.warning("This operation is irreversible!")
|
|
58
|
+
if not fmt.confirm(confirm_msg):
|
|
59
|
+
fmt.echo("Deletion cancelled.")
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
fmt.echo(f"Deleting {operation}...")
|
|
63
|
+
|
|
64
|
+
# Run the async delete function
|
|
65
|
+
async def run_delete():
|
|
66
|
+
try:
|
|
67
|
+
if args.all:
|
|
68
|
+
await cognee.delete(dataset_name=None, user_id=args.user_id)
|
|
69
|
+
else:
|
|
70
|
+
await cognee.delete(dataset_name=args.dataset_name, user_id=args.user_id)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
raise CliCommandInnerException(f"Failed to delete: {str(e)}")
|
|
73
|
+
|
|
74
|
+
asyncio.run(run_delete())
|
|
75
|
+
fmt.success(f"Successfully deleted {operation}")
|
|
76
|
+
|
|
77
|
+
except Exception as e:
|
|
78
|
+
if isinstance(e, CliCommandInnerException):
|
|
79
|
+
raise CliCommandException(str(e), error_code=1)
|
|
80
|
+
raise CliCommandException(f"Error deleting data: {str(e)}", error_code=1)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from cognee.cli.reference import SupportsCliCommand
|
|
7
|
+
from cognee.cli import DEFAULT_DOCS_URL
|
|
8
|
+
from cognee.cli.config import SEARCH_TYPE_CHOICES, OUTPUT_FORMAT_CHOICES
|
|
9
|
+
import cognee.cli.echo as fmt
|
|
10
|
+
from cognee.cli.exceptions import CliCommandException, CliCommandInnerException
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SearchCommand(SupportsCliCommand):
|
|
14
|
+
command_string = "search"
|
|
15
|
+
help_string = "Search and query the knowledge graph for insights, information, and connections"
|
|
16
|
+
docs_url = DEFAULT_DOCS_URL
|
|
17
|
+
description = """
|
|
18
|
+
Search and query the knowledge graph for insights, information, and connections.
|
|
19
|
+
|
|
20
|
+
This is the final step in the Cognee workflow that retrieves information from the
|
|
21
|
+
processed knowledge graph. It supports multiple search modes optimized for different
|
|
22
|
+
use cases - from simple fact retrieval to complex reasoning and code analysis.
|
|
23
|
+
|
|
24
|
+
Search Types & Use Cases:
|
|
25
|
+
|
|
26
|
+
**GRAPH_COMPLETION** (Default - Recommended):
|
|
27
|
+
Natural language Q&A using full graph context and LLM reasoning.
|
|
28
|
+
Best for: Complex questions, analysis, summaries, insights.
|
|
29
|
+
|
|
30
|
+
**RAG_COMPLETION**:
|
|
31
|
+
Traditional RAG using document chunks without graph structure.
|
|
32
|
+
Best for: Direct document retrieval, specific fact-finding.
|
|
33
|
+
|
|
34
|
+
**INSIGHTS**:
|
|
35
|
+
Structured entity relationships and semantic connections.
|
|
36
|
+
Best for: Understanding concept relationships, knowledge mapping.
|
|
37
|
+
|
|
38
|
+
**CHUNKS**:
|
|
39
|
+
Raw text segments that match the query semantically.
|
|
40
|
+
Best for: Finding specific passages, citations, exact content.
|
|
41
|
+
|
|
42
|
+
**SUMMARIES**:
|
|
43
|
+
Pre-generated hierarchical summaries of content.
|
|
44
|
+
Best for: Quick overviews, document abstracts, topic summaries.
|
|
45
|
+
|
|
46
|
+
**CODE**:
|
|
47
|
+
Code-specific search with syntax and semantic understanding.
|
|
48
|
+
Best for: Finding functions, classes, implementation patterns.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
52
|
+
parser.add_argument("query_text", help="Your question or search query in natural language")
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
"--query-type",
|
|
55
|
+
"-t",
|
|
56
|
+
choices=SEARCH_TYPE_CHOICES,
|
|
57
|
+
default="GRAPH_COMPLETION",
|
|
58
|
+
help="Search mode (default: GRAPH_COMPLETION for conversational AI responses)",
|
|
59
|
+
)
|
|
60
|
+
parser.add_argument(
|
|
61
|
+
"--datasets",
|
|
62
|
+
"-d",
|
|
63
|
+
nargs="*",
|
|
64
|
+
help="Dataset name(s) to search within. Searches all accessible datasets if not specified",
|
|
65
|
+
)
|
|
66
|
+
parser.add_argument(
|
|
67
|
+
"--top-k",
|
|
68
|
+
"-k",
|
|
69
|
+
type=int,
|
|
70
|
+
default=10,
|
|
71
|
+
help="Maximum number of results to return (default: 10, max: 100)",
|
|
72
|
+
)
|
|
73
|
+
parser.add_argument(
|
|
74
|
+
"--system-prompt",
|
|
75
|
+
help="Custom system prompt file for LLM-based search types (default: answer_simple_question.txt)",
|
|
76
|
+
)
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"--output-format",
|
|
79
|
+
"-f",
|
|
80
|
+
choices=OUTPUT_FORMAT_CHOICES,
|
|
81
|
+
default="pretty",
|
|
82
|
+
help="Output format (default: pretty)",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def execute(self, args: argparse.Namespace) -> None:
|
|
86
|
+
try:
|
|
87
|
+
# Import cognee here to avoid circular imports
|
|
88
|
+
import cognee
|
|
89
|
+
from cognee.modules.search.types import SearchType
|
|
90
|
+
|
|
91
|
+
# Convert string to SearchType enum
|
|
92
|
+
query_type = SearchType[args.query_type]
|
|
93
|
+
|
|
94
|
+
datasets_msg = (
|
|
95
|
+
f" in datasets {args.datasets}" if args.datasets else " across all datasets"
|
|
96
|
+
)
|
|
97
|
+
fmt.echo(f"Searching for: '{args.query_text}' (type: {args.query_type}){datasets_msg}")
|
|
98
|
+
|
|
99
|
+
# Run the async search function
|
|
100
|
+
async def run_search():
|
|
101
|
+
try:
|
|
102
|
+
results = await cognee.search(
|
|
103
|
+
query_text=args.query_text,
|
|
104
|
+
query_type=query_type,
|
|
105
|
+
datasets=args.datasets,
|
|
106
|
+
system_prompt_path=args.system_prompt or "answer_simple_question.txt",
|
|
107
|
+
top_k=args.top_k,
|
|
108
|
+
)
|
|
109
|
+
return results
|
|
110
|
+
except Exception as e:
|
|
111
|
+
raise CliCommandInnerException(f"Failed to search: {str(e)}")
|
|
112
|
+
|
|
113
|
+
results = asyncio.run(run_search())
|
|
114
|
+
|
|
115
|
+
# Format and display results
|
|
116
|
+
if args.output_format == "json":
|
|
117
|
+
fmt.echo(json.dumps(results, indent=2, default=str))
|
|
118
|
+
elif args.output_format == "simple":
|
|
119
|
+
for i, result in enumerate(results, 1):
|
|
120
|
+
fmt.echo(f"{i}. {result}")
|
|
121
|
+
else: # pretty format
|
|
122
|
+
if not results:
|
|
123
|
+
fmt.warning("No results found for your query.")
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
fmt.echo(f"\nFound {len(results)} result(s) using {args.query_type}:")
|
|
127
|
+
fmt.echo("=" * 60)
|
|
128
|
+
|
|
129
|
+
if args.query_type in ["GRAPH_COMPLETION", "RAG_COMPLETION"]:
|
|
130
|
+
# These return conversational responses
|
|
131
|
+
for i, result in enumerate(results, 1):
|
|
132
|
+
fmt.echo(f"{fmt.bold('Response:')} {result}")
|
|
133
|
+
if i < len(results):
|
|
134
|
+
fmt.echo("-" * 40)
|
|
135
|
+
elif args.query_type == "CHUNKS":
|
|
136
|
+
# These return text chunks
|
|
137
|
+
for i, result in enumerate(results, 1):
|
|
138
|
+
fmt.echo(f"{fmt.bold(f'Chunk {i}:')} {result}")
|
|
139
|
+
fmt.echo()
|
|
140
|
+
else:
|
|
141
|
+
# Generic formatting for other types
|
|
142
|
+
for i, result in enumerate(results, 1):
|
|
143
|
+
fmt.echo(f"{fmt.bold(f'Result {i}:')} {result}")
|
|
144
|
+
fmt.echo()
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
if isinstance(e, CliCommandInnerException):
|
|
148
|
+
raise CliCommandException(str(e), error_code=1)
|
|
149
|
+
raise CliCommandException(f"Error searching: {str(e)}", error_code=1)
|
cognee/cli/config.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI configuration and constants to avoid hardcoded values
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# CLI Constants
|
|
6
|
+
CLI_DESCRIPTION = "Cognee CLI - Manage your knowledge graphs and cognitive processing pipelines."
|
|
7
|
+
DEFAULT_DOCS_URL = "https://docs.cognee.ai"
|
|
8
|
+
|
|
9
|
+
# Command descriptions - these should match the actual command implementations
|
|
10
|
+
COMMAND_DESCRIPTIONS = {
|
|
11
|
+
"add": "Add data to Cognee for knowledge graph processing",
|
|
12
|
+
"search": "Search and query the knowledge graph for insights, information, and connections",
|
|
13
|
+
"cognify": "Transform ingested data into a structured knowledge graph",
|
|
14
|
+
"delete": "Delete data from cognee knowledge base",
|
|
15
|
+
"config": "Manage cognee configuration settings",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Search type choices
|
|
19
|
+
SEARCH_TYPE_CHOICES = [
|
|
20
|
+
"GRAPH_COMPLETION",
|
|
21
|
+
"RAG_COMPLETION",
|
|
22
|
+
"INSIGHTS",
|
|
23
|
+
"CHUNKS",
|
|
24
|
+
"SUMMARIES",
|
|
25
|
+
"CODE",
|
|
26
|
+
"CYPHER",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
# Chunker choices
|
|
30
|
+
CHUNKER_CHOICES = ["TextChunker", "LangchainChunker"]
|
|
31
|
+
|
|
32
|
+
# Output format choices
|
|
33
|
+
OUTPUT_FORMAT_CHOICES = ["json", "pretty", "simple"]
|
cognee/cli/debug.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Provides a global debug setting for the CLI - following dlt patterns"""
|
|
2
|
+
|
|
3
|
+
_DEBUG_FLAG = False
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def enable_debug() -> None:
|
|
7
|
+
"""Enable debug mode for CLI"""
|
|
8
|
+
global _DEBUG_FLAG
|
|
9
|
+
_DEBUG_FLAG = True
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def disable_debug() -> None:
|
|
13
|
+
"""Disable debug mode for CLI"""
|
|
14
|
+
global _DEBUG_FLAG
|
|
15
|
+
_DEBUG_FLAG = False
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def is_debug_enabled() -> bool:
|
|
19
|
+
"""Check if debug mode is enabled"""
|
|
20
|
+
global _DEBUG_FLAG
|
|
21
|
+
return _DEBUG_FLAG
|
cognee/cli/echo.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""CLI output formatting utilities"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import click
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def echo(message: str = "", color: str = None, err: bool = False) -> None:
|
|
9
|
+
"""Echo a message to stdout or stderr with optional color"""
|
|
10
|
+
click.secho(message, fg=color, err=err)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def note(message: str) -> None:
|
|
14
|
+
"""Print a note in blue"""
|
|
15
|
+
echo(f"Note: {message}", color="blue")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def warning(message: str) -> None:
|
|
19
|
+
"""Print a warning in yellow"""
|
|
20
|
+
echo(f"Warning: {message}", color="yellow")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def error(message: str) -> None:
|
|
24
|
+
"""Print an error in red"""
|
|
25
|
+
echo(f"Error: {message}", color="red", err=True)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def success(message: str) -> None:
|
|
29
|
+
"""Print a success message in green"""
|
|
30
|
+
echo(f"Success: {message}", color="green")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def bold(text: str) -> str:
|
|
34
|
+
"""Make text bold"""
|
|
35
|
+
return click.style(text, bold=True)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def confirm(message: str, default: bool = False) -> bool:
|
|
39
|
+
"""Ask for user confirmation"""
|
|
40
|
+
return click.confirm(message, default=default)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def prompt(message: str, default: Any = None) -> str:
|
|
44
|
+
"""Prompt user for input"""
|
|
45
|
+
return click.prompt(message, default=default)
|