graphiti-core 0.21.0rc10__tar.gz → 0.21.0rc12__tar.gz
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.
Potentially problematic release.
This version of graphiti-core might be problematic. Click here for more details.
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/claude-code-review.yml +1 -0
- graphiti_core-0.21.0rc12/.github/workflows/daily_issue_maintenance.yml +123 -0
- graphiti_core-0.21.0rc12/.github/workflows/issue-triage.yml +140 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/PKG-INFO +1 -1
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/edges.py +6 -3
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/graphiti.py +1 -11
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/graphiti_types.py +0 -1
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/nodes.py +6 -3
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/dedupe_edges.py +40 -29
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/dedupe_nodes.py +10 -9
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/eval.py +3 -3
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/extract_edges.py +17 -9
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/extract_nodes.py +7 -7
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/prompt_helpers.py +3 -3
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/summarize_nodes.py +5 -5
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search_helpers.py +5 -7
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/bulk_utils.py +0 -1
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/community_operations.py +8 -20
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/edge_operations.py +40 -14
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/node_operations.py +46 -13
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/temporal_operations.py +0 -4
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/pyproject.toml +1 -1
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/utils/maintenance/test_bulk_utils.py +0 -2
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/utils/maintenance/test_edge_operations.py +0 -8
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/utils/maintenance/test_node_operations.py +0 -10
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/uv.lock +1 -1
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.env.example +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/dependabot.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/pull_request_template.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/secret_scanning.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/ai-moderator.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/cla.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/claude.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/codeql.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/lint.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/mcp-server-docker.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/release-graphiti-core.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/typecheck.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.github/workflows/unit_tests.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/.gitignore +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/AGENTS.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/CLAUDE.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/CODE_OF_CONDUCT.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/CONTRIBUTING.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/Dockerfile +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/LICENSE +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/Makefile +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/README.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/SECURITY.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/Zep-CLA.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/conftest.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/depot.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/docker-compose.test.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/docker-compose.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/ellipsis.yaml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/data/manybirds_products.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/ecommerce/runner.ipynb +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/ecommerce/runner.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/langgraph-agent/agent.ipynb +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/langgraph-agent/tinybirds-jess.png +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/podcast/podcast_runner.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/podcast/podcast_transcript.txt +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/podcast/transcript_parser.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/quickstart/README.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/quickstart/quickstart_falkordb.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/quickstart/quickstart_neo4j.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/quickstart/quickstart_neptune.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/quickstart/requirements.txt +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/wizard_of_oz/parser.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/wizard_of_oz/runner.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/examples/wizard_of_oz/woo.txt +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/cross_encoder/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/cross_encoder/client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/cross_encoder/gemini_reranker_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/cross_encoder/openai_reranker_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/falkordb_driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/kuzu_driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/neo4j_driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/driver/neptune_driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/azure_openai.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/gemini.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/openai.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/embedder/voyage.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/errors.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/graph_queries.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/helpers.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/anthropic_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/azure_openai_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/config.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/errors.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/gemini_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/groq_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/openai_base_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/openai_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/openai_generic_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/llm_client/utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/migrations/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/models/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/models/edges/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/models/edges/edge_db_queries.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/models/nodes/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/models/nodes/node_db_queries.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/extract_edge_dates.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/invalidate_edges.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/lib.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/models.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/py.typed +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search_config.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search_config_recipes.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search_filters.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/search/search_utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/telemetry/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/telemetry/telemetry.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/datetime_utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/dedup_helpers.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/graph_data_operations.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/maintenance/utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/utils/ontology_utils/entity_types_utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/images/arxiv-screenshot.png +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/images/graphiti-graph-intro.gif +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/images/graphiti-intro-slides-stock-2.gif +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/images/simple_graph.svg +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/.env.example +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/.python-version +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/Dockerfile +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/README.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/cursor_rules.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/docker-compose.yml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/graphiti_mcp_server.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/mcp_config_sse_example.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/mcp_config_stdio_example.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/pyproject.toml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/mcp_server/uv.lock +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/py.typed +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/pytest.ini +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/.env.example +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/Makefile +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/README.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/config.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/dto/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/dto/common.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/dto/ingest.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/dto/retrieve.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/main.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/routers/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/routers/ingest.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/routers/retrieve.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/graph_service/zep_graphiti.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/pyproject.toml +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/server/uv.lock +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/signatures/version1/cla.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/cross_encoder/test_bge_reranker_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/cross_encoder/test_gemini_reranker_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/driver/__init__.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/driver/test_falkordb_driver.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/embedder/embedder_fixtures.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/embedder/test_gemini.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/embedder/test_openai.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/embedder/test_voyage.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/data/longmemeval_data/README.md +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/data/longmemeval_data/longmemeval_oracle.json +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/eval_cli.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/eval_e2e_graph_building.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/pytest.ini +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/evals/utils.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/helpers_test.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/llm_client/test_anthropic_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/llm_client/test_anthropic_client_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/llm_client/test_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/llm_client/test_errors.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/llm_client/test_gemini_client.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/test_edge_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/test_entity_exclusion_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/test_graphiti_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/test_graphiti_mock.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/test_node_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/utils/maintenance/test_temporal_operations_int.py +0 -0
- {graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/tests/utils/search/search_utils_test.py +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
name: Daily Issue Maintenance
|
|
2
|
+
on:
|
|
3
|
+
schedule:
|
|
4
|
+
- cron: "0 0 * * *" # Every day at midnight
|
|
5
|
+
workflow_dispatch: # Manual trigger option
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
find-legacy-duplicates:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
if: github.event_name == 'workflow_dispatch'
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
issues: write
|
|
14
|
+
id-token: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 1
|
|
19
|
+
|
|
20
|
+
- uses: anthropics/claude-code-action@v1
|
|
21
|
+
with:
|
|
22
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
23
|
+
prompt: |
|
|
24
|
+
REPO: ${{ github.repository }}
|
|
25
|
+
|
|
26
|
+
Find potential duplicate issues in the repository:
|
|
27
|
+
|
|
28
|
+
1. Use `gh issue list --state open --limit 1000 --json number,title,body,createdAt` to get all open issues
|
|
29
|
+
2. For each issue, search for potential duplicates using `gh search issues` with keywords from the title and body
|
|
30
|
+
3. Compare issues to identify true duplicates using these criteria:
|
|
31
|
+
- Same bug or error being reported
|
|
32
|
+
- Same feature request (even if worded differently)
|
|
33
|
+
- Same question being asked
|
|
34
|
+
- Issues describing the same root problem
|
|
35
|
+
|
|
36
|
+
For each duplicate found:
|
|
37
|
+
- Add a comment linking to the original issue
|
|
38
|
+
- Apply the "duplicate" label using `gh issue edit`
|
|
39
|
+
- Be polite and explain why it's a duplicate
|
|
40
|
+
|
|
41
|
+
Focus on finding true duplicates, not just similar issues.
|
|
42
|
+
|
|
43
|
+
claude_args: |
|
|
44
|
+
--allowedTools "Bash(gh issue:*),Bash(gh search:*)"
|
|
45
|
+
--model claude-sonnet-4-5-20250929
|
|
46
|
+
|
|
47
|
+
check-stale-issues:
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
if: github.event_name == 'schedule'
|
|
50
|
+
permissions:
|
|
51
|
+
contents: read
|
|
52
|
+
issues: write
|
|
53
|
+
id-token: write
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
with:
|
|
57
|
+
fetch-depth: 1
|
|
58
|
+
|
|
59
|
+
- uses: anthropics/claude-code-action@v1
|
|
60
|
+
with:
|
|
61
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
62
|
+
prompt: |
|
|
63
|
+
REPO: ${{ github.repository }}
|
|
64
|
+
|
|
65
|
+
Review stale issues and request confirmation:
|
|
66
|
+
|
|
67
|
+
1. Use `gh issue list --state open --limit 1000 --json number,title,updatedAt,comments` to get all open issues
|
|
68
|
+
2. Identify issues that are:
|
|
69
|
+
- Older than 60 days (based on updatedAt)
|
|
70
|
+
- Have no comments with "stale-check" label
|
|
71
|
+
- Are not labeled as "enhancement" or "documentation"
|
|
72
|
+
3. For each stale issue:
|
|
73
|
+
- Add a polite comment asking the issue originator if this is still relevant
|
|
74
|
+
- Apply a "stale-check" label to track that we've asked
|
|
75
|
+
- Use format: "@{author} Is this still an issue? Please confirm within 14 days or this issue will be closed."
|
|
76
|
+
|
|
77
|
+
Use:
|
|
78
|
+
- `gh issue view` to check issue details and labels
|
|
79
|
+
- `gh issue comment` to add comments
|
|
80
|
+
- `gh issue edit` to add the "stale-check" label
|
|
81
|
+
|
|
82
|
+
claude_args: |
|
|
83
|
+
--allowedTools "Bash(gh issue:*)"
|
|
84
|
+
--model claude-sonnet-4-5-20250929
|
|
85
|
+
|
|
86
|
+
close-unconfirmed-issues:
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
if: github.event_name == 'schedule'
|
|
89
|
+
needs: check-stale-issues
|
|
90
|
+
permissions:
|
|
91
|
+
contents: read
|
|
92
|
+
issues: write
|
|
93
|
+
id-token: write
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v4
|
|
96
|
+
with:
|
|
97
|
+
fetch-depth: 1
|
|
98
|
+
|
|
99
|
+
- uses: anthropics/claude-code-action@v1
|
|
100
|
+
with:
|
|
101
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
102
|
+
prompt: |
|
|
103
|
+
REPO: ${{ github.repository }}
|
|
104
|
+
|
|
105
|
+
Close unconfirmed stale issues:
|
|
106
|
+
|
|
107
|
+
1. Use `gh issue list --state open --label "stale-check" --limit 1000 --json number,title,comments,updatedAt` to get issues with stale-check label
|
|
108
|
+
2. For each issue, check if:
|
|
109
|
+
- The "stale-check" comment was added 14+ days ago
|
|
110
|
+
- There has been no response from the issue author or activity since the comment
|
|
111
|
+
3. For issues meeting the criteria:
|
|
112
|
+
- Add a polite closing comment
|
|
113
|
+
- Close the issue using `gh issue close`
|
|
114
|
+
- Use format: "Closing due to inactivity. Feel free to reopen if this is still relevant."
|
|
115
|
+
|
|
116
|
+
Use:
|
|
117
|
+
- `gh issue view` to check issue comments and activity
|
|
118
|
+
- `gh issue comment` to add closing comment
|
|
119
|
+
- `gh issue close` to close the issue
|
|
120
|
+
|
|
121
|
+
claude_args: |
|
|
122
|
+
--allowedTools "Bash(gh issue:*)"
|
|
123
|
+
--model claude-sonnet-4-5-20250929
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
name: Issue Triage and Deduplication
|
|
2
|
+
on:
|
|
3
|
+
issues:
|
|
4
|
+
types: [opened]
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
triage:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
timeout-minutes: 10
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
issues: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 1
|
|
20
|
+
|
|
21
|
+
- name: Run Claude Code for Issue Triage
|
|
22
|
+
uses: anthropics/claude-code-action@v1
|
|
23
|
+
with:
|
|
24
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
25
|
+
allowed_non_write_users: "*"
|
|
26
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
prompt: |
|
|
28
|
+
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.
|
|
29
|
+
|
|
30
|
+
IMPORTANT: Don't post any comments or messages to the issue. Your only action should be to apply labels. DO NOT check for duplicates - that's handled by a separate job.
|
|
31
|
+
|
|
32
|
+
Issue Information:
|
|
33
|
+
- REPO: ${{ github.repository }}
|
|
34
|
+
- ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
35
|
+
|
|
36
|
+
TASK OVERVIEW:
|
|
37
|
+
|
|
38
|
+
1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.
|
|
39
|
+
|
|
40
|
+
2. Next, use gh commands to get context about the issue:
|
|
41
|
+
- Use `gh issue view ${{ github.event.issue.number }}` to retrieve the current issue's details
|
|
42
|
+
- Use `gh search issues` to find similar issues that might provide context for proper categorization
|
|
43
|
+
- You have access to these Bash commands:
|
|
44
|
+
- Bash(gh label list:*) - to get available labels
|
|
45
|
+
- Bash(gh issue view:*) - to view issue details
|
|
46
|
+
- Bash(gh issue edit:*) - to apply labels to the issue
|
|
47
|
+
- Bash(gh search:*) - to search for similar issues
|
|
48
|
+
|
|
49
|
+
3. Analyze the issue content, considering:
|
|
50
|
+
- The issue title and description
|
|
51
|
+
- The type of issue (bug report, feature request, question, etc.)
|
|
52
|
+
- Technical areas mentioned
|
|
53
|
+
- Database mentions (neo4j, falkordb, neptune, etc.)
|
|
54
|
+
- LLM providers mentioned (openai, anthropic, gemini, groq, etc.)
|
|
55
|
+
- Components affected (embeddings, search, prompts, server, mcp, etc.)
|
|
56
|
+
|
|
57
|
+
4. Select appropriate labels from the available labels list:
|
|
58
|
+
- Choose labels that accurately reflect the issue's nature
|
|
59
|
+
- Be specific but comprehensive
|
|
60
|
+
- Add database-specific labels if mentioned: neo4j, falkordb, neptune
|
|
61
|
+
- Add component labels if applicable
|
|
62
|
+
- DO NOT add priority labels (P1, P2, P3)
|
|
63
|
+
- DO NOT add duplicate label - that's handled by the deduplication job
|
|
64
|
+
|
|
65
|
+
5. Apply the selected labels:
|
|
66
|
+
- Use `gh issue edit ${{ github.event.issue.number }} --add-label "label1,label2,label3"` to apply your selected labels
|
|
67
|
+
- DO NOT post any comments explaining your decision
|
|
68
|
+
- DO NOT communicate directly with users
|
|
69
|
+
- If no labels are clearly applicable, do not apply any labels
|
|
70
|
+
|
|
71
|
+
IMPORTANT GUIDELINES:
|
|
72
|
+
- Be thorough in your analysis
|
|
73
|
+
- Only select labels from the provided list
|
|
74
|
+
- DO NOT post any comments to the issue
|
|
75
|
+
- Your ONLY action should be to apply labels using gh issue edit
|
|
76
|
+
- It's okay to not add any labels if none are clearly applicable
|
|
77
|
+
- DO NOT check for duplicates
|
|
78
|
+
|
|
79
|
+
claude_args: |
|
|
80
|
+
--allowedTools "Bash(gh label list:*),Bash(gh issue view:*),Bash(gh issue edit:*),Bash(gh search:*)"
|
|
81
|
+
--model claude-sonnet-4-5-20250929
|
|
82
|
+
|
|
83
|
+
deduplicate:
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
timeout-minutes: 10
|
|
86
|
+
needs: triage
|
|
87
|
+
permissions:
|
|
88
|
+
contents: read
|
|
89
|
+
issues: write
|
|
90
|
+
id-token: write
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Checkout repository
|
|
94
|
+
uses: actions/checkout@v4
|
|
95
|
+
with:
|
|
96
|
+
fetch-depth: 1
|
|
97
|
+
|
|
98
|
+
- name: Check for duplicate issues
|
|
99
|
+
uses: anthropics/claude-code-action@v1
|
|
100
|
+
with:
|
|
101
|
+
prompt: |
|
|
102
|
+
Analyze this new issue and check if it's a duplicate of existing issues in the repository.
|
|
103
|
+
|
|
104
|
+
Issue: #${{ github.event.issue.number }}
|
|
105
|
+
Repository: ${{ github.repository }}
|
|
106
|
+
|
|
107
|
+
Your task:
|
|
108
|
+
1. Use mcp__github__get_issue to get details of the current issue (#${{ github.event.issue.number }})
|
|
109
|
+
2. Search for similar existing OPEN issues using mcp__github__search_issues with relevant keywords from the issue title and body
|
|
110
|
+
3. Compare the new issue with existing ones to identify potential duplicates
|
|
111
|
+
|
|
112
|
+
Criteria for duplicates:
|
|
113
|
+
- Same bug or error being reported
|
|
114
|
+
- Same feature request (even if worded differently)
|
|
115
|
+
- Same question being asked
|
|
116
|
+
- Issues describing the same root problem
|
|
117
|
+
|
|
118
|
+
If you find duplicates:
|
|
119
|
+
- Add a comment on the new issue linking to the original issue(s)
|
|
120
|
+
- Apply the "duplicate" label to the new issue
|
|
121
|
+
- Be polite and explain why it's a duplicate
|
|
122
|
+
- Suggest the user follow the original issue for updates
|
|
123
|
+
|
|
124
|
+
If it's NOT a duplicate:
|
|
125
|
+
- Don't add any comments
|
|
126
|
+
- Don't modify labels
|
|
127
|
+
|
|
128
|
+
Use these tools:
|
|
129
|
+
- mcp__github__get_issue: Get issue details
|
|
130
|
+
- mcp__github__search_issues: Search for similar issues (use state:open)
|
|
131
|
+
- mcp__github__list_issues: List recent issues if needed
|
|
132
|
+
- mcp__github__create_issue_comment: Add a comment if duplicate found
|
|
133
|
+
- mcp__github__update_issue: Add "duplicate" label
|
|
134
|
+
|
|
135
|
+
Be thorough but efficient. Focus on finding true duplicates, not just similar issues.
|
|
136
|
+
|
|
137
|
+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
138
|
+
claude_args: |
|
|
139
|
+
--allowedTools "mcp__github__get_issue,mcp__github__search_issues,mcp__github__list_issues,mcp__github__create_issue_comment,mcp__github__update_issue,mcp__github__get_issue_comments"
|
|
140
|
+
--model claude-sonnet-4-5-20250929
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphiti-core
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.0rc12
|
|
4
4
|
Summary: A temporal graph building library
|
|
5
5
|
Project-URL: Homepage, https://help.getzep.com/graphiti/graphiti/overview
|
|
6
6
|
Project-URL: Repository, https://github.com/getzep/graphiti
|
|
@@ -644,8 +644,11 @@ def get_community_edge_from_record(record: Any):
|
|
|
644
644
|
|
|
645
645
|
|
|
646
646
|
async def create_entity_edge_embeddings(embedder: EmbedderClient, edges: list[EntityEdge]):
|
|
647
|
-
|
|
647
|
+
# filter out falsey values from edges
|
|
648
|
+
filtered_edges = [edge for edge in edges if edge.fact]
|
|
649
|
+
|
|
650
|
+
if len(filtered_edges) == 0:
|
|
648
651
|
return
|
|
649
|
-
fact_embeddings = await embedder.create_batch([edge.fact for edge in
|
|
650
|
-
for edge, fact_embedding in zip(
|
|
652
|
+
fact_embeddings = await embedder.create_batch([edge.fact for edge in filtered_edges])
|
|
653
|
+
for edge, fact_embedding in zip(filtered_edges, fact_embeddings, strict=True):
|
|
651
654
|
edge.fact_embedding = fact_embedding
|
|
@@ -136,7 +136,6 @@ class Graphiti:
|
|
|
136
136
|
store_raw_episode_content: bool = True,
|
|
137
137
|
graph_driver: GraphDriver | None = None,
|
|
138
138
|
max_coroutines: int | None = None,
|
|
139
|
-
ensure_ascii: bool = False,
|
|
140
139
|
):
|
|
141
140
|
"""
|
|
142
141
|
Initialize a Graphiti instance.
|
|
@@ -169,10 +168,6 @@ class Graphiti:
|
|
|
169
168
|
max_coroutines : int | None, optional
|
|
170
169
|
The maximum number of concurrent operations allowed. Overrides SEMAPHORE_LIMIT set in the environment.
|
|
171
170
|
If not set, the Graphiti default is used.
|
|
172
|
-
ensure_ascii : bool, optional
|
|
173
|
-
Whether to escape non-ASCII characters in JSON serialization for prompts. Defaults to False.
|
|
174
|
-
Set as False to preserve non-ASCII characters (e.g., Korean, Japanese, Chinese) in their
|
|
175
|
-
original form, making them readable in LLM logs and improving model understanding.
|
|
176
171
|
|
|
177
172
|
Returns
|
|
178
173
|
-------
|
|
@@ -202,7 +197,6 @@ class Graphiti:
|
|
|
202
197
|
|
|
203
198
|
self.store_raw_episode_content = store_raw_episode_content
|
|
204
199
|
self.max_coroutines = max_coroutines
|
|
205
|
-
self.ensure_ascii = ensure_ascii
|
|
206
200
|
if llm_client:
|
|
207
201
|
self.llm_client = llm_client
|
|
208
202
|
else:
|
|
@@ -221,7 +215,6 @@ class Graphiti:
|
|
|
221
215
|
llm_client=self.llm_client,
|
|
222
216
|
embedder=self.embedder,
|
|
223
217
|
cross_encoder=self.cross_encoder,
|
|
224
|
-
ensure_ascii=self.ensure_ascii,
|
|
225
218
|
)
|
|
226
219
|
|
|
227
220
|
# Capture telemetry event
|
|
@@ -559,9 +552,7 @@ class Graphiti:
|
|
|
559
552
|
if update_communities:
|
|
560
553
|
communities, community_edges = await semaphore_gather(
|
|
561
554
|
*[
|
|
562
|
-
update_community(
|
|
563
|
-
self.driver, self.llm_client, self.embedder, node, self.ensure_ascii
|
|
564
|
-
)
|
|
555
|
+
update_community(self.driver, self.llm_client, self.embedder, node)
|
|
565
556
|
for node in nodes
|
|
566
557
|
],
|
|
567
558
|
max_coroutines=self.max_coroutines,
|
|
@@ -1071,7 +1062,6 @@ class Graphiti:
|
|
|
1071
1062
|
),
|
|
1072
1063
|
None,
|
|
1073
1064
|
None,
|
|
1074
|
-
self.ensure_ascii,
|
|
1075
1065
|
)
|
|
1076
1066
|
|
|
1077
1067
|
edges: list[EntityEdge] = [resolved_edge] + invalidated_edges
|
|
@@ -868,9 +868,12 @@ def get_community_node_from_record(record: Any) -> CommunityNode:
|
|
|
868
868
|
|
|
869
869
|
|
|
870
870
|
async def create_entity_node_embeddings(embedder: EmbedderClient, nodes: list[EntityNode]):
|
|
871
|
-
|
|
871
|
+
# filter out falsey values from nodes
|
|
872
|
+
filtered_nodes = [node for node in nodes if node.name]
|
|
873
|
+
|
|
874
|
+
if not filtered_nodes:
|
|
872
875
|
return
|
|
873
876
|
|
|
874
|
-
name_embeddings = await embedder.create_batch([node.name for node in
|
|
875
|
-
for node, name_embedding in zip(
|
|
877
|
+
name_embeddings = await embedder.create_batch([node.name for node in filtered_nodes])
|
|
878
|
+
for node, name_embedding in zip(filtered_nodes, name_embeddings, strict=True):
|
|
876
879
|
node.name_embedding = name_embedding
|
|
@@ -25,11 +25,11 @@ from .prompt_helpers import to_prompt_json
|
|
|
25
25
|
class EdgeDuplicate(BaseModel):
|
|
26
26
|
duplicate_facts: list[int] = Field(
|
|
27
27
|
...,
|
|
28
|
-
description='List of
|
|
28
|
+
description='List of idx values of any duplicate facts. If no duplicate facts are found, default to empty list.',
|
|
29
29
|
)
|
|
30
30
|
contradicted_facts: list[int] = Field(
|
|
31
31
|
...,
|
|
32
|
-
description='List of
|
|
32
|
+
description='List of idx values of facts that should be invalidated. If no facts should be invalidated, the list should be empty.',
|
|
33
33
|
)
|
|
34
34
|
fact_type: str = Field(..., description='One of the provided fact types or DEFAULT')
|
|
35
35
|
|
|
@@ -67,11 +67,11 @@ def edge(context: dict[str, Any]) -> list[Message]:
|
|
|
67
67
|
Given the following context, determine whether the New Edge represents any of the edges in the list of Existing Edges.
|
|
68
68
|
|
|
69
69
|
<EXISTING EDGES>
|
|
70
|
-
{to_prompt_json(context['related_edges'],
|
|
70
|
+
{to_prompt_json(context['related_edges'], indent=2)}
|
|
71
71
|
</EXISTING EDGES>
|
|
72
72
|
|
|
73
73
|
<NEW EDGE>
|
|
74
|
-
{to_prompt_json(context['extracted_edges'],
|
|
74
|
+
{to_prompt_json(context['extracted_edges'], indent=2)}
|
|
75
75
|
</NEW EDGE>
|
|
76
76
|
|
|
77
77
|
Task:
|
|
@@ -98,7 +98,7 @@ def edge_list(context: dict[str, Any]) -> list[Message]:
|
|
|
98
98
|
Given the following context, find all of the duplicates in a list of facts:
|
|
99
99
|
|
|
100
100
|
Facts:
|
|
101
|
-
{to_prompt_json(context['edges'],
|
|
101
|
+
{to_prompt_json(context['edges'], indent=2)}
|
|
102
102
|
|
|
103
103
|
Task:
|
|
104
104
|
If any facts in Facts is a duplicate of another fact, return a new fact with one of their uuid's.
|
|
@@ -124,37 +124,48 @@ def resolve_edge(context: dict[str, Any]) -> list[Message]:
|
|
|
124
124
|
Message(
|
|
125
125
|
role='user',
|
|
126
126
|
content=f"""
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
Task:
|
|
128
|
+
You will receive TWO separate lists of facts. Each list uses 'idx' as its index field, starting from 0.
|
|
129
|
+
|
|
130
|
+
1. DUPLICATE DETECTION:
|
|
131
|
+
- If the NEW FACT represents identical factual information as any fact in EXISTING FACTS, return those idx values in duplicate_facts.
|
|
132
|
+
- Facts with similar information that contain key differences should NOT be marked as duplicates.
|
|
133
|
+
- Return idx values from EXISTING FACTS.
|
|
134
|
+
- If no duplicates, return an empty list for duplicate_facts.
|
|
135
|
+
|
|
136
|
+
2. FACT TYPE CLASSIFICATION:
|
|
137
|
+
- Given the predefined FACT TYPES, determine if the NEW FACT should be classified as one of these types.
|
|
138
|
+
- Return the fact type as fact_type or DEFAULT if NEW FACT is not one of the FACT TYPES.
|
|
139
|
+
|
|
140
|
+
3. CONTRADICTION DETECTION:
|
|
141
|
+
- Based on FACT INVALIDATION CANDIDATES and NEW FACT, determine which facts the new fact contradicts.
|
|
142
|
+
- Return idx values from FACT INVALIDATION CANDIDATES.
|
|
143
|
+
- If no contradictions, return an empty list for contradicted_facts.
|
|
144
|
+
|
|
145
|
+
IMPORTANT:
|
|
146
|
+
- duplicate_facts: Use ONLY 'idx' values from EXISTING FACTS
|
|
147
|
+
- contradicted_facts: Use ONLY 'idx' values from FACT INVALIDATION CANDIDATES
|
|
148
|
+
- These are two separate lists with independent idx ranges starting from 0
|
|
149
|
+
|
|
150
|
+
Guidelines:
|
|
151
|
+
1. Some facts may be very similar but will have key differences, particularly around numeric values in the facts.
|
|
152
|
+
Do not mark these facts as duplicates.
|
|
153
|
+
|
|
154
|
+
<FACT TYPES>
|
|
155
|
+
{context['edge_types']}
|
|
156
|
+
</FACT TYPES>
|
|
157
|
+
|
|
131
158
|
<EXISTING FACTS>
|
|
132
159
|
{context['existing_edges']}
|
|
133
160
|
</EXISTING FACTS>
|
|
161
|
+
|
|
134
162
|
<FACT INVALIDATION CANDIDATES>
|
|
135
163
|
{context['edge_invalidation_candidates']}
|
|
136
164
|
</FACT INVALIDATION CANDIDATES>
|
|
137
|
-
|
|
138
|
-
<FACT TYPES>
|
|
139
|
-
{context['edge_types']}
|
|
140
|
-
</FACT TYPES>
|
|
141
|
-
|
|
142
165
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
If the NEW FACT is not a duplicate of any of the EXISTING FACTS, return an empty list.
|
|
147
|
-
|
|
148
|
-
Given the predefined FACT TYPES, determine if the NEW FACT should be classified as one of these types.
|
|
149
|
-
Return the fact type as fact_type or DEFAULT if NEW FACT is not one of the FACT TYPES.
|
|
150
|
-
|
|
151
|
-
Based on the provided FACT INVALIDATION CANDIDATES and NEW FACT, determine which existing facts the new fact contradicts.
|
|
152
|
-
Return a list containing all idx's of the facts that are contradicted by the NEW FACT.
|
|
153
|
-
If there are no contradicted facts, return an empty list.
|
|
154
|
-
|
|
155
|
-
Guidelines:
|
|
156
|
-
1. Some facts may be very similar but will have key differences, particularly around numeric values in the facts.
|
|
157
|
-
Do not mark these facts as duplicates.
|
|
166
|
+
<NEW FACT>
|
|
167
|
+
{context['new_edge']}
|
|
168
|
+
</NEW FACT>
|
|
158
169
|
""",
|
|
159
170
|
),
|
|
160
171
|
]
|
|
@@ -64,20 +64,20 @@ def node(context: dict[str, Any]) -> list[Message]:
|
|
|
64
64
|
role='user',
|
|
65
65
|
content=f"""
|
|
66
66
|
<PREVIOUS MESSAGES>
|
|
67
|
-
{to_prompt_json([ep for ep in context['previous_episodes']],
|
|
67
|
+
{to_prompt_json([ep for ep in context['previous_episodes']], indent=2)}
|
|
68
68
|
</PREVIOUS MESSAGES>
|
|
69
69
|
<CURRENT MESSAGE>
|
|
70
70
|
{context['episode_content']}
|
|
71
71
|
</CURRENT MESSAGE>
|
|
72
72
|
<NEW ENTITY>
|
|
73
|
-
{to_prompt_json(context['extracted_node'],
|
|
73
|
+
{to_prompt_json(context['extracted_node'], indent=2)}
|
|
74
74
|
</NEW ENTITY>
|
|
75
75
|
<ENTITY TYPE DESCRIPTION>
|
|
76
|
-
{to_prompt_json(context['entity_type_description'],
|
|
76
|
+
{to_prompt_json(context['entity_type_description'], indent=2)}
|
|
77
77
|
</ENTITY TYPE DESCRIPTION>
|
|
78
78
|
|
|
79
79
|
<EXISTING ENTITIES>
|
|
80
|
-
{to_prompt_json(context['existing_nodes'],
|
|
80
|
+
{to_prompt_json(context['existing_nodes'], indent=2)}
|
|
81
81
|
</EXISTING ENTITIES>
|
|
82
82
|
|
|
83
83
|
Given the above EXISTING ENTITIES and their attributes, MESSAGE, and PREVIOUS MESSAGES; Determine if the NEW ENTITY extracted from the conversation
|
|
@@ -125,7 +125,7 @@ def nodes(context: dict[str, Any]) -> list[Message]:
|
|
|
125
125
|
role='user',
|
|
126
126
|
content=f"""
|
|
127
127
|
<PREVIOUS MESSAGES>
|
|
128
|
-
{to_prompt_json([ep for ep in context['previous_episodes']],
|
|
128
|
+
{to_prompt_json([ep for ep in context['previous_episodes']], indent=2)}
|
|
129
129
|
</PREVIOUS MESSAGES>
|
|
130
130
|
<CURRENT MESSAGE>
|
|
131
131
|
{context['episode_content']}
|
|
@@ -142,11 +142,11 @@ def nodes(context: dict[str, Any]) -> list[Message]:
|
|
|
142
142
|
}}
|
|
143
143
|
|
|
144
144
|
<ENTITIES>
|
|
145
|
-
{to_prompt_json(context['extracted_nodes'],
|
|
145
|
+
{to_prompt_json(context['extracted_nodes'], indent=2)}
|
|
146
146
|
</ENTITIES>
|
|
147
147
|
|
|
148
148
|
<EXISTING ENTITIES>
|
|
149
|
-
{to_prompt_json(context['existing_nodes'],
|
|
149
|
+
{to_prompt_json(context['existing_nodes'], indent=2)}
|
|
150
150
|
</EXISTING ENTITIES>
|
|
151
151
|
|
|
152
152
|
Each entry in EXISTING ENTITIES is an object with the following structure:
|
|
@@ -166,7 +166,8 @@ def nodes(context: dict[str, Any]) -> list[Message]:
|
|
|
166
166
|
- They have similar names or purposes but refer to separate instances or concepts.
|
|
167
167
|
|
|
168
168
|
Task:
|
|
169
|
-
|
|
169
|
+
ENTITIES contains {len(context['extracted_nodes'])} entities with IDs 0 through {len(context['extracted_nodes']) - 1}.
|
|
170
|
+
Your response MUST include EXACTLY {len(context['extracted_nodes'])} resolutions with IDs 0 through {len(context['extracted_nodes']) - 1}. Do not skip or add IDs.
|
|
170
171
|
|
|
171
172
|
For every entity, return an object with the following keys:
|
|
172
173
|
{{
|
|
@@ -196,7 +197,7 @@ def node_list(context: dict[str, Any]) -> list[Message]:
|
|
|
196
197
|
Given the following context, deduplicate a list of nodes:
|
|
197
198
|
|
|
198
199
|
Nodes:
|
|
199
|
-
{to_prompt_json(context['nodes'],
|
|
200
|
+
{to_prompt_json(context['nodes'], indent=2)}
|
|
200
201
|
|
|
201
202
|
Task:
|
|
202
203
|
1. Group nodes together such that all duplicate nodes are in the same list of uuids
|
|
@@ -68,7 +68,7 @@ def query_expansion(context: dict[str, Any]) -> list[Message]:
|
|
|
68
68
|
Bob is asking Alice a question, are you able to rephrase the question into a simpler one about Alice in the third person
|
|
69
69
|
that maintains the relevant context?
|
|
70
70
|
<QUESTION>
|
|
71
|
-
{to_prompt_json(context['query']
|
|
71
|
+
{to_prompt_json(context['query'])}
|
|
72
72
|
</QUESTION>
|
|
73
73
|
"""
|
|
74
74
|
return [
|
|
@@ -84,10 +84,10 @@ def qa_prompt(context: dict[str, Any]) -> list[Message]:
|
|
|
84
84
|
Your task is to briefly answer the question in the way that you think Alice would answer the question.
|
|
85
85
|
You are given the following entity summaries and facts to help you determine the answer to your question.
|
|
86
86
|
<ENTITY_SUMMARIES>
|
|
87
|
-
{to_prompt_json(context['entity_summaries']
|
|
87
|
+
{to_prompt_json(context['entity_summaries'])}
|
|
88
88
|
</ENTITY_SUMMARIES>
|
|
89
89
|
<FACTS>
|
|
90
|
-
{to_prompt_json(context['facts']
|
|
90
|
+
{to_prompt_json(context['facts'])}
|
|
91
91
|
</FACTS>
|
|
92
92
|
<QUESTION>
|
|
93
93
|
{context['query']}
|
{graphiti_core-0.21.0rc10 → graphiti_core-0.21.0rc12}/graphiti_core/prompts/extract_edges.py
RENAMED
|
@@ -24,9 +24,16 @@ from .prompt_helpers import to_prompt_json
|
|
|
24
24
|
|
|
25
25
|
class Edge(BaseModel):
|
|
26
26
|
relation_type: str = Field(..., description='FACT_PREDICATE_IN_SCREAMING_SNAKE_CASE')
|
|
27
|
-
source_entity_id: int = Field(
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
source_entity_id: int = Field(
|
|
28
|
+
..., description='The id of the source entity from the ENTITIES list'
|
|
29
|
+
)
|
|
30
|
+
target_entity_id: int = Field(
|
|
31
|
+
..., description='The id of the target entity from the ENTITIES list'
|
|
32
|
+
)
|
|
33
|
+
fact: str = Field(
|
|
34
|
+
...,
|
|
35
|
+
description='A natural language description of the relationship between the entities, paraphrased from the source text',
|
|
36
|
+
)
|
|
30
37
|
valid_at: str | None = Field(
|
|
31
38
|
None,
|
|
32
39
|
description='The date and time when the relationship described by the edge fact became true or was established. Use ISO 8601 format (YYYY-MM-DDTHH:MM:SS.SSSSSSZ)',
|
|
@@ -73,7 +80,7 @@ def edge(context: dict[str, Any]) -> list[Message]:
|
|
|
73
80
|
</FACT TYPES>
|
|
74
81
|
|
|
75
82
|
<PREVIOUS_MESSAGES>
|
|
76
|
-
{to_prompt_json([ep for ep in context['previous_episodes']],
|
|
83
|
+
{to_prompt_json([ep for ep in context['previous_episodes']], indent=2)}
|
|
77
84
|
</PREVIOUS_MESSAGES>
|
|
78
85
|
|
|
79
86
|
<CURRENT_MESSAGE>
|
|
@@ -81,7 +88,7 @@ def edge(context: dict[str, Any]) -> list[Message]:
|
|
|
81
88
|
</CURRENT_MESSAGE>
|
|
82
89
|
|
|
83
90
|
<ENTITIES>
|
|
84
|
-
{context['nodes']}
|
|
91
|
+
{to_prompt_json(context['nodes'], indent=2)}
|
|
85
92
|
</ENTITIES>
|
|
86
93
|
|
|
87
94
|
<REFERENCE_TIME>
|
|
@@ -107,11 +114,12 @@ You may use information from the PREVIOUS MESSAGES only to disambiguate referenc
|
|
|
107
114
|
|
|
108
115
|
# EXTRACTION RULES
|
|
109
116
|
|
|
110
|
-
1.
|
|
117
|
+
1. **Entity ID Validation**: `source_entity_id` and `target_entity_id` must use only the `id` values from the ENTITIES list provided above.
|
|
118
|
+
- **CRITICAL**: Using IDs not in the list will cause the edge to be rejected
|
|
111
119
|
2. Each fact must involve two **distinct** entities.
|
|
112
120
|
3. Use a SCREAMING_SNAKE_CASE string as the `relation_type` (e.g., FOUNDED, WORKS_AT).
|
|
113
121
|
4. Do not emit duplicate or semantically redundant facts.
|
|
114
|
-
5. The `
|
|
122
|
+
5. The `fact` should closely paraphrase the original source sentence(s). Do not verbatim quote the original text.
|
|
115
123
|
6. Use `REFERENCE_TIME` to resolve vague or relative temporal expressions (e.g., "last week").
|
|
116
124
|
7. Do **not** hallucinate or infer temporal bounds from unrelated events.
|
|
117
125
|
|
|
@@ -133,7 +141,7 @@ def reflexion(context: dict[str, Any]) -> list[Message]:
|
|
|
133
141
|
|
|
134
142
|
user_prompt = f"""
|
|
135
143
|
<PREVIOUS MESSAGES>
|
|
136
|
-
{to_prompt_json([ep for ep in context['previous_episodes']],
|
|
144
|
+
{to_prompt_json([ep for ep in context['previous_episodes']], indent=2)}
|
|
137
145
|
</PREVIOUS MESSAGES>
|
|
138
146
|
<CURRENT MESSAGE>
|
|
139
147
|
{context['episode_content']}
|
|
@@ -167,7 +175,7 @@ def extract_attributes(context: dict[str, Any]) -> list[Message]:
|
|
|
167
175
|
content=f"""
|
|
168
176
|
|
|
169
177
|
<MESSAGE>
|
|
170
|
-
{to_prompt_json(context['episode_content'],
|
|
178
|
+
{to_prompt_json(context['episode_content'], indent=2)}
|
|
171
179
|
</MESSAGE>
|
|
172
180
|
<REFERENCE TIME>
|
|
173
181
|
{context['reference_time']}
|