conductor-checkpoint-msg_01WRZxPMQYjNEjcFNTMzWYeL

This commit is contained in:
Daniel Chalef 2025-10-30 11:25:25 -07:00
parent ca0092d510
commit 58bad9b542
10 changed files with 335 additions and 87 deletions

View file

@ -23,7 +23,7 @@ The Graphiti MCP server provides comprehensive knowledge graph capabilities:
- **Graph Database Support**: Multiple backend options including Kuzu (default), Neo4j, and FalkorDB
- **Multiple LLM Providers**: Support for OpenAI, Anthropic, Gemini, Groq, and Azure OpenAI
- **Multiple Embedding Providers**: Support for OpenAI, Voyage, Sentence Transformers, and Gemini embeddings
- **Custom Entity Types**: Define and use custom entity types for domain-specific knowledge extraction
- **Rich Entity Types**: Built-in entity types including Preferences, Requirements, Procedures, Locations, Events, Organizations, Documents, and more for structured knowledge extraction
- **HTTP Transport**: Default HTTP transport with MCP endpoint at `/mcp/` for broad client compatibility
- **Queue-based Processing**: Asynchronous episode processing with configurable concurrency limits
@ -187,6 +187,36 @@ embedder:
Make sure Ollama is running locally with: `ollama serve`
### Entity Types
Graphiti MCP Server includes built-in entity types for structured knowledge extraction. These entity types are always enabled and configured via the `entity_types` section in your `config.yaml`:
**Available Entity Types:**
- **Preference**: User preferences, choices, opinions, or selections (prioritized for user-specific information)
- **Requirement**: Specific needs, features, or functionality that must be fulfilled
- **Procedure**: Standard operating procedures and sequential instructions
- **Location**: Physical or virtual places where activities occur
- **Event**: Time-bound activities, occurrences, or experiences
- **Organization**: Companies, institutions, groups, or formal entities
- **Document**: Information content in various forms (books, articles, reports, videos, etc.)
- **Topic**: Subject of conversation, interest, or knowledge domain (used as a fallback)
- **Object**: Physical items, tools, devices, or possessions (used as a fallback)
These entity types are defined in `config.yaml` and can be customized by modifying the descriptions:
```yaml
graphiti:
entity_types:
- name: "Preference"
description: "User preferences, choices, opinions, or selections"
- name: "Requirement"
description: "Specific needs, features, or functionality"
# ... additional entity types
```
The MCP server automatically uses these entity types during episode ingestion to extract and structure information from conversations and documents.
### Environment Variables
The `config.yaml` file supports environment variable expansion using `${VAR_NAME}` or `${VAR_NAME:default}` syntax. Key variables:
@ -292,7 +322,6 @@ uv run graphiti_mcp_server.py --config config/config-docker-falkordb.yaml
- `--transport`: Choose the transport method (http or stdio, default: http)
- `--group-id`: Set a namespace for the graph (optional). If not provided, defaults to "main"
- `--destroy-graph`: If set, destroys all Graphiti graphs on startup
- `--use-custom-entities`: Enable entity extraction using the predefined ENTITY_TYPES
### Concurrency and LLM Provider 429 Rate Limit Errors
@ -505,7 +534,7 @@ To integrate the Graphiti MCP Server with the Cursor IDE, follow these steps:
1. Run the Graphiti MCP server using the default HTTP transport:
```bash
uv run graphiti_mcp_server.py --use-custom-entities --group-id <your_group_id>
uv run graphiti_mcp_server.py --group-id <your_group_id>
```
Hint: specify a `group_id` to namespace graph data. If you do not specify a `group_id`, the server will use "main" as the group_id.

View file

@ -81,9 +81,21 @@ graphiti:
episode_id_prefix: ${EPISODE_ID_PREFIX:}
user_id: ${USER_ID:mcp_user}
entity_types:
- name: "Requirement"
description: "Represents a requirement"
- name: "Preference"
description: "User preferences and settings"
description: "User preferences, choices, opinions, or selections (PRIORITIZE over most other types except User/Assistant)"
- name: "Requirement"
description: "Specific needs, features, or functionality that must be fulfilled"
- name: "Procedure"
description: "Standard operating procedures"
description: "Standard operating procedures and sequential instructions"
- name: "Location"
description: "Physical or virtual places where activities occur"
- name: "Event"
description: "Time-bound activities, occurrences, or experiences"
- name: "Organization"
description: "Companies, institutions, groups, or formal entities"
- name: "Document"
description: "Information content in various forms (books, articles, reports, etc.)"
- name: "Topic"
description: "Subject of conversation, interest, or knowledge domain (use as last resort)"
- name: "Object"
description: "Physical items, tools, devices, or possessions (use as last resort)"

View file

@ -81,9 +81,21 @@ graphiti:
episode_id_prefix: ${EPISODE_ID_PREFIX:}
user_id: ${USER_ID:mcp_user}
entity_types:
- name: "Requirement"
description: "Represents a requirement"
- name: "Preference"
description: "User preferences and settings"
description: "User preferences, choices, opinions, or selections (PRIORITIZE over most other types except User/Assistant)"
- name: "Requirement"
description: "Specific needs, features, or functionality that must be fulfilled"
- name: "Procedure"
description: "Standard operating procedures"
description: "Standard operating procedures and sequential instructions"
- name: "Location"
description: "Physical or virtual places where activities occur"
- name: "Event"
description: "Time-bound activities, occurrences, or experiences"
- name: "Organization"
description: "Companies, institutions, groups, or formal entities"
- name: "Document"
description: "Information content in various forms (books, articles, reports, etc.)"
- name: "Topic"
description: "Subject of conversation, interest, or knowledge domain (use as last resort)"
- name: "Object"
description: "Physical items, tools, devices, or possessions (use as last resort)"

View file

@ -83,9 +83,21 @@ graphiti:
episode_id_prefix: ${EPISODE_ID_PREFIX:}
user_id: ${USER_ID:mcp_user}
entity_types:
- name: "Requirement"
description: "Represents a requirement"
- name: "Preference"
description: "User preferences and settings"
description: "User preferences, choices, opinions, or selections (PRIORITIZE over most other types except User/Assistant)"
- name: "Requirement"
description: "Specific needs, features, or functionality that must be fulfilled"
- name: "Procedure"
description: "Standard operating procedures"
description: "Standard operating procedures and sequential instructions"
- name: "Location"
description: "Physical or virtual places where activities occur"
- name: "Event"
description: "Time-bound activities, occurrences, or experiences"
- name: "Organization"
description: "Companies, institutions, groups, or formal entities"
- name: "Document"
description: "Information content in various forms (books, articles, reports, etc.)"
- name: "Topic"
description: "Subject of conversation, interest, or knowledge domain (use as last resort)"
- name: "Object"
description: "Physical items, tools, devices, or possessions (use as last resort)"

View file

@ -91,9 +91,21 @@ graphiti:
episode_id_prefix: ${EPISODE_ID_PREFIX:}
user_id: ${USER_ID:mcp_user}
entity_types:
- name: "Requirement"
description: "Represents a requirement"
- name: "Preference"
description: "User preferences and settings"
description: "User preferences, choices, opinions, or selections (PRIORITIZE over most other types except User/Assistant)"
- name: "Requirement"
description: "Specific needs, features, or functionality that must be fulfilled"
- name: "Procedure"
description: "Standard operating procedures"
description: "Standard operating procedures and sequential instructions"
- name: "Location"
description: "Physical or virtual places where activities occur"
- name: "Event"
description: "Time-bound activities, occurrences, or experiences"
- name: "Organization"
description: "Companies, institutions, groups, or formal entities"
- name: "Document"
description: "Information content in various forms (books, articles, reports, etc.)"
- name: "Topic"
description: "Subject of conversation, interest, or knowledge domain (use as last resort)"
- name: "Object"
description: "Physical items, tools, devices, or possessions (use as last resort)"

View file

@ -151,7 +151,9 @@ class LLMConfig(BaseModel):
provider: str = Field(default='openai', description='LLM provider')
model: str = Field(default='gpt-4.1', description='Model name')
temperature: float | None = Field(default=None, description='Temperature (optional, defaults to None for reasoning models)')
temperature: float | None = Field(
default=None, description='Temperature (optional, defaults to None for reasoning models)'
)
max_tokens: int = Field(default=4096, description='Max tokens')
providers: LLMProvidersConfig = Field(default_factory=LLMProvidersConfig)
@ -240,7 +242,6 @@ class GraphitiConfig(BaseSettings):
graphiti: GraphitiAppConfig = Field(default_factory=GraphitiAppConfig)
# Additional server options
use_custom_entities: bool = Field(default=False, description='Enable custom entity types')
destroy_graph: bool = Field(default=False, description='Clear graph on startup')
model_config = SettingsConfigDict(

View file

@ -21,7 +21,6 @@ from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel
from config.schema import GraphitiConfig, ServerConfig
from models.entity_types import ENTITY_TYPES
from models.response_types import (
EpisodeSearchResponse,
ErrorResponse,
@ -82,6 +81,7 @@ def configure_uvicorn_logging():
uvicorn_logger.addHandler(handler)
uvicorn_logger.propagate = False
logger = logging.getLogger(__name__)
# Create global config instance - will be properly initialized later
@ -165,7 +165,7 @@ class GraphitiService:
# Get database configuration
db_config = DatabaseDriverFactory.create_config(self.config.database)
# Build custom entity types if configured
# Build entity types from configuration
custom_types = None
if self.config.graphiti.entity_types:
custom_types = {}
@ -180,13 +180,6 @@ class GraphitiService:
},
)
custom_types[entity_type.name] = entity_model
# Also support the existing ENTITY_TYPES if use_custom_entities is set
elif hasattr(self.config, 'use_custom_entities') and self.config.use_custom_entities:
# Convert ENTITY_TYPES list to dict if needed
if isinstance(ENTITY_TYPES, list):
custom_types = {et.__name__: et for et in ENTITY_TYPES}
else:
custom_types = ENTITY_TYPES
# Store entity types for later use
self.entity_types = custom_types
@ -678,7 +671,8 @@ async def get_status() -> StatusResponse:
if config.database.provider.lower() == 'kuzu':
provider_info = f'{config.database.provider} database (in-memory)'
return StatusResponse(
status='ok', message=f'Graphiti MCP server is running and connected to {provider_info}'
status='ok',
message=f'Graphiti MCP server is running and connected to {provider_info}',
)
# For Neo4j and FalkorDB, test connection with a simple query
@ -776,11 +770,6 @@ async def initialize_server() -> ServerConfig:
action='store_true',
help='Destroy all Graphiti graphs on startup',
)
parser.add_argument(
'--use-custom-entities',
action='store_true',
help='Enable entity extraction using the predefined ENTITY_TYPES',
)
args = parser.parse_args()
@ -795,8 +784,6 @@ async def initialize_server() -> ServerConfig:
config.apply_cli_overrides(args)
# Also apply legacy CLI args for backward compatibility
if hasattr(args, 'use_custom_entities'):
config.use_custom_entities = args.use_custom_entities
if hasattr(args, 'destroy_graph'):
config.destroy_graph = args.destroy_graph
@ -811,6 +798,7 @@ async def initialize_server() -> ServerConfig:
# Log graphiti-core version
try:
import graphiti_core
graphiti_version = getattr(graphiti_core, '__version__', 'unknown')
logger.info(f' - Graphiti Core: {graphiti_version}')
except Exception:

View file

@ -76,8 +76,162 @@ class Procedure(BaseModel):
)
class Location(BaseModel):
"""A Location represents a physical or virtual place where activities occur or entities exist.
IMPORTANT: Before using this classification, first check if the entity is a:
User, Assistant, Preference, Organization, Document, Event - if so, use those instead.
Instructions for identifying and extracting locations:
1. Look for mentions of physical places (cities, buildings, rooms, addresses)
2. Identify virtual locations (websites, online platforms, virtual meeting rooms)
3. Extract specific location names rather than generic references
4. Include relevant context about the location's purpose or significance
5. Pay attention to location hierarchies (e.g., "conference room in Building A")
6. Capture both permanent locations and temporary venues
7. Note any significant activities or events associated with the location
"""
name: str = Field(
...,
description='The name or identifier of the location',
)
description: str = Field(
...,
description='Brief description of the location and its significance. Only use information mentioned in the context.',
)
class Event(BaseModel):
"""An Event represents a time-bound activity, occurrence, or experience.
Instructions for identifying and extracting events:
1. Look for activities with specific time frames (meetings, appointments, deadlines)
2. Identify planned or scheduled occurrences (vacations, projects, celebrations)
3. Extract unplanned occurrences (accidents, interruptions, discoveries)
4. Capture the purpose or nature of the event
5. Include temporal information when available (past, present, future, duration)
6. Note participants or stakeholders involved in the event
7. Identify outcomes or consequences of the event when mentioned
8. Extract both recurring events and one-time occurrences
"""
name: str = Field(
...,
description='The name or title of the event',
)
description: str = Field(
...,
description='Brief description of the event. Only use information mentioned in the context.',
)
class Object(BaseModel):
"""An Object represents a physical item, tool, device, or possession.
IMPORTANT: Use this classification ONLY as a last resort. First check if entity fits into:
User, Assistant, Preference, Organization, Document, Event, Location, Topic - if so, use those instead.
Instructions for identifying and extracting objects:
1. Look for mentions of physical items or possessions (car, phone, equipment)
2. Identify tools or devices used for specific purposes
3. Extract items that are owned, used, or maintained by entities
4. Include relevant attributes (brand, model, condition) when mentioned
5. Note the object's purpose or function when specified
6. Capture relationships between objects and their owners or users
7. Avoid extracting objects that are better classified as Documents or other types
"""
name: str = Field(
...,
description='The name or identifier of the object',
)
description: str = Field(
...,
description='Brief description of the object. Only use information mentioned in the context.',
)
class Topic(BaseModel):
"""A Topic represents a subject of conversation, interest, or knowledge domain.
IMPORTANT: Use this classification ONLY as a last resort. First check if entity fits into:
User, Assistant, Preference, Organization, Document, Event, Location - if so, use those instead.
Instructions for identifying and extracting topics:
1. Look for subjects being discussed or areas of interest (health, technology, sports)
2. Identify knowledge domains or fields of study
3. Extract themes that span multiple conversations or contexts
4. Include specific subtopics when mentioned (e.g., "machine learning" rather than just "AI")
5. Capture topics associated with projects, work, or hobbies
6. Note the context in which the topic appears
7. Avoid extracting topics that are better classified as Events, Documents, or Organizations
"""
name: str = Field(
...,
description='The name or identifier of the topic',
)
description: str = Field(
...,
description='Brief description of the topic and its context. Only use information mentioned in the context.',
)
class Organization(BaseModel):
"""An Organization represents a company, institution, group, or formal entity.
Instructions for identifying and extracting organizations:
1. Look for company names, employers, and business entities
2. Identify institutions (schools, hospitals, government agencies)
3. Extract formal groups (clubs, teams, associations)
4. Include organizational type when mentioned (company, nonprofit, agency)
5. Capture relationships between people and organizations (employer, member)
6. Note the organization's industry or domain when specified
7. Extract both large entities and small groups if formally organized
"""
name: str = Field(
...,
description='The name of the organization',
)
description: str = Field(
...,
description='Brief description of the organization. Only use information mentioned in the context.',
)
class Document(BaseModel):
"""A Document represents information content in various forms.
Instructions for identifying and extracting documents:
1. Look for references to written or recorded content (books, articles, reports)
2. Identify digital content (emails, videos, podcasts, presentations)
3. Extract specific document titles or identifiers when available
4. Include document type (report, article, video) when mentioned
5. Capture the document's purpose or subject matter
6. Note relationships to authors, creators, or sources
7. Include document status (draft, published, archived) when mentioned
"""
title: str = Field(
...,
description='The title or identifier of the document',
)
description: str = Field(
...,
description='Brief description of the document and its content. Only use information mentioned in the context.',
)
ENTITY_TYPES: dict[str, BaseModel] = {
'Requirement': Requirement, # type: ignore
'Preference': Preference, # type: ignore
'Procedure': Procedure, # type: ignore
'Location': Location, # type: ignore
'Event': Event, # type: ignore
'Object': Object, # type: ignore
'Topic': Topic, # type: ignore
'Organization': Organization, # type: ignore
'Document': Document, # type: ignore
}

View file

@ -94,7 +94,9 @@ def _validate_and_mask_api_key(provider_name: str, api_key: str | None, logger)
ValueError: If API key is None or empty
"""
if not api_key:
raise ValueError(f'{provider_name} API key is not configured. Please set the appropriate environment variable.')
raise ValueError(
f'{provider_name} API key is not configured. Please set the appropriate environment variable.'
)
# Log masked API key for debugging
masked_key = f'{api_key[:7]}...{api_key[-4:]}' if len(api_key) > 11 else '***'
@ -110,6 +112,7 @@ class LLMClientFactory:
def create(config: LLMConfig) -> LLMClient:
"""Create an LLM client based on the configured provider."""
import logging
logger = logging.getLogger(__name__)
provider = config.provider.lower()
@ -125,16 +128,14 @@ class LLMClientFactory:
from graphiti_core.llm_client.config import LLMConfig as CoreLLMConfig
# Determine appropriate small model based on main model type
small_model = None
is_reasoning_model = (
config.model.startswith('gpt-5')
or config.model.startswith('o1')
or config.model.startswith('o3')
)
if is_reasoning_model:
small_model = 'gpt-5-nano' # Use reasoning model for small tasks too
else:
small_model = 'gpt-4.1-mini' # Use non-reasoning model for small tasks
small_model = (
'gpt-5-nano' if is_reasoning_model else 'gpt-4.1-mini'
) # Use reasoning model for small tasks if main model is reasoning
llm_config = CoreLLMConfig(
api_key=api_key,
@ -152,18 +153,10 @@ class LLMClientFactory:
)
if is_reasoning_model:
return OpenAIClient(
config=llm_config,
reasoning='minimal',
verbosity='low'
)
return OpenAIClient(config=llm_config, reasoning='minimal', verbosity='low')
else:
# For non-reasoning models, explicitly pass None to disable these parameters
return OpenAIClient(
config=llm_config,
reasoning=None,
verbosity=None
)
return OpenAIClient(config=llm_config, reasoning=None, verbosity=None)
case 'azure_openai':
if not HAS_AZURE_LLM:
@ -278,6 +271,7 @@ class EmbedderFactory:
def create(config: EmbedderConfig) -> EmbedderClient:
"""Create an Embedder client based on the configured provider."""
import logging
logger = logging.getLogger(__name__)
provider = config.provider.lower()
@ -314,7 +308,9 @@ class EmbedderFactory:
api_key: str | None = None
azure_ad_token_provider = None
if azure_config.use_azure_ad:
logger.info('Creating Azure OpenAI Embedder client with Azure AD authentication')
logger.info(
'Creating Azure OpenAI Embedder client with Azure AD authentication'
)
azure_ad_token_provider = create_azure_credential_token_provider()
else:
api_key = azure_config.api_key

96
mcp_server/uv.lock generated
View file

@ -488,6 +488,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8e/98/2c050dec90e295a524c9b65c4cb9e7c302386a296b2938710448cbd267d5/faker-37.12.0-py3-none-any.whl", hash = "sha256:afe7ccc038da92f2fbae30d8e16d19d91e92e242f8401ce9caf44de892bab4c4", size = 1975461, upload-time = "2025-10-24T15:19:55.739Z" },
]
[[package]]
name = "falkordb"
version = "1.2.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dateutil" },
{ name = "redis" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9e/3b/2d846e877aec104841c523e99e1c584d4aa2423a0e31afee5b8369e3c8c5/falkordb-1.2.0.tar.gz", hash = "sha256:ce57365b86722d538e75aa5d438de67ecd8eb9478da612506d9812cd7f182d0b", size = 28976, upload-time = "2025-06-30T18:03:37.829Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/81/1265e623c989bb8c12fe566645bad390d04e66fa62b84ca656e5bafce1f0/falkordb-1.2.0-py3-none-any.whl", hash = "sha256:7572d9cc377735d22efc52fe6fe73c7a435422c827b6ea3ca223a850a77be12e", size = 34737, upload-time = "2025-06-30T18:03:36.582Z" },
]
[[package]]
name = "filelock"
version = "3.19.1"
@ -648,6 +661,14 @@ dependencies = [
{ name = "tenacity" },
]
[package.optional-dependencies]
falkordb = [
{ name = "falkordb" },
]
kuzu = [
{ name = "kuzu" },
]
[package.metadata]
requires-dist = [
{ name = "anthropic", marker = "extra == 'anthropic'", specifier = ">=0.49.0" },
@ -930,36 +951,36 @@ wheels = [
[[package]]
name = "kuzu"
version = "0.11.2"
version = "0.11.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/66/fd/adbd05ccf81e6ad2674fcd3849d5d6ffeaf2141a9b8d1c1c4e282e923e1f/kuzu-0.11.2.tar.gz", hash = "sha256:9f224ec218ab165a18acaea903695779780d70335baf402d9b7f59ba389db0bd", size = 4902887, upload-time = "2025-08-21T05:17:00.152Z" }
sdist = { url = "https://files.pythonhosted.org/packages/96/0c/f141a81485729a072dc527b474e7580d5632309c68ad1a5aa6ed9ac45387/kuzu-0.11.3.tar.gz", hash = "sha256:e7bea3ca30c4bb462792eedcaa7f2125c800b243bb4a872e1eedc16917c1967a", size = 19430620, upload-time = "2025-10-10T13:36:54.984Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0e/91/bed837f5f49220a9f869da8a078b34a3484f210f7b57b267177821545c03/kuzu-0.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b25174cdb721aae47896ed62842d3859679607b493a9a6bbbcd9fb7fb3707", size = 3702618, upload-time = "2025-08-21T05:15:53.726Z" },
{ url = "https://files.pythonhosted.org/packages/72/8a/fd5e053b0055718afe00b6a99393a835c6254354128fbb7f66a35fd76089/kuzu-0.11.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9a8567c53bfe282f4727782471ff718842ffead8c48c1762c1df9197408fc986", size = 4101371, upload-time = "2025-08-21T05:15:55.889Z" },
{ url = "https://files.pythonhosted.org/packages/ad/4b/e45cadc85bdc5079f432675bbe8d557600f0d4ab46fe24ef218374419902/kuzu-0.11.2-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d793bb5a0a14ada730a697eccac2a4c68b434b82692d985942900ef2003e099e", size = 6211974, upload-time = "2025-08-21T05:15:57.505Z" },
{ url = "https://files.pythonhosted.org/packages/10/ca/92d6a1e6452fcf06bfc423ce2cde819ace6b6e47921921cc8fae87c27780/kuzu-0.11.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1be4e9b6c93ca8591b1fb165f9b9a27d70a56af061831afcdfe7aebb89ee6ff", size = 6992196, upload-time = "2025-08-21T05:15:59.006Z" },
{ url = "https://files.pythonhosted.org/packages/49/6c/983fc6265dfc1169c87c4a0722f36ee665c5688e1166faeb4cd85e6af078/kuzu-0.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0ec7a304c746a2a98ecfd7e7c3f6fe92c4dfee2e2565c0b7cb4cffd0c2e374a", size = 4303517, upload-time = "2025-08-21T05:16:00.814Z" },
{ url = "https://files.pythonhosted.org/packages/b5/14/8ae2c52657b93715052ecf47d70232f2c8d9ffe2d1ec3527c8e9c3cb2df5/kuzu-0.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf53b4f321a4c05882b14cef96d39a1e90fa993bab88a1554fb1565367553b8c", size = 3704177, upload-time = "2025-08-21T05:16:02.354Z" },
{ url = "https://files.pythonhosted.org/packages/2d/7a/bce7bb755e16f9ca855f76a3acc6cfa9fae88c4d6af9df3784c50b2120a5/kuzu-0.11.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:2d749883b74f5da5ff4a4b0635a98f6cc5165743995828924321d2ca797317cb", size = 4102372, upload-time = "2025-08-21T05:16:04.249Z" },
{ url = "https://files.pythonhosted.org/packages/c8/12/f5b1d51fcb78a86c078fb85cc53184ce962a3e86852d47d30e287a932e3f/kuzu-0.11.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:632507e5982928ed24fbb5e70ad143d7970bc4059046e77e0522707efbad303b", size = 6212492, upload-time = "2025-08-21T05:16:05.99Z" },
{ url = "https://files.pythonhosted.org/packages/81/96/d6e57af6ccf9e0697812ad3039c80b87b768cf2674833b0b23d317ea3427/kuzu-0.11.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5211884601f8f08ae97ba25006d0facde24077c5333411d944282b8a2068ab4", size = 6992888, upload-time = "2025-08-21T05:16:07.896Z" },
{ url = "https://files.pythonhosted.org/packages/40/ee/1f275ac5679a3f615ce0d9cf8c79001fdb535ccc8bc344e49b14484c7cd7/kuzu-0.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:82a6c8bfe1278dc1010790e398bf772683797ef5c16052fa0f6f78bacbc59aa3", size = 4304064, upload-time = "2025-08-21T05:16:10.163Z" },
{ url = "https://files.pythonhosted.org/packages/73/ba/9f20d9e83681a0ddae8ec13046b116c34745fa0e66862d4e2d8414734ce0/kuzu-0.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aed88ffa695d07289a3d8557bd8f9e743298a4f4349208a60bbb06f4ebf15c26", size = 3703781, upload-time = "2025-08-21T05:16:12.232Z" },
{ url = "https://files.pythonhosted.org/packages/53/a0/bb815c0490f3d4d30389156369b9fe641e154f0d4b1e8340f09a76021922/kuzu-0.11.2-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:595824b03248af928e3faee57f6825d3a46920f2d3b9bd0c0bb7fc3fa097fce9", size = 4103990, upload-time = "2025-08-21T05:16:14.139Z" },
{ url = "https://files.pythonhosted.org/packages/a5/6f/97b647c0547a634a669055ff4cfd21a92ea3999aedc6a7fe9004f03f25e3/kuzu-0.11.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5674c6d9d26f5caa0c7ce6f34c02e4411894879aa5b2ce174fad576fa898523", size = 6211947, upload-time = "2025-08-21T05:16:16.48Z" },
{ url = "https://files.pythonhosted.org/packages/42/74/c7f1a1cfb08c05c91c5a94483be387e80fafab8923c4243a22e9cced5c1b/kuzu-0.11.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c61daf02da35b671f4c6f3c17105725c399a5e14b7349b00eafbcd24ac90034a", size = 6991879, upload-time = "2025-08-21T05:16:18.402Z" },
{ url = "https://files.pythonhosted.org/packages/54/9e/50d67d7bc08faed95ede6de1a6aa0d81079c98028ca99e32d09c2ab1aead/kuzu-0.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:682096cd87dcbb8257f933ea4172d9dc5617a8d0a5bdd19cd66cf05b68881afd", size = 4305706, upload-time = "2025-08-21T05:16:20.244Z" },
{ url = "https://files.pythonhosted.org/packages/65/f0/5649a01af37def50293cd7c194afc19f09b343fd2b7f2b28e021a207f8ce/kuzu-0.11.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:17a11b67652e8b331c85cd1a1a30b32ee6783750084473abbab2aa1963ee2a3b", size = 3703740, upload-time = "2025-08-21T05:16:21.896Z" },
{ url = "https://files.pythonhosted.org/packages/24/e2/e0beb9080911fc1689899a42da0f83534949f43169fb80197def3ec1223f/kuzu-0.11.2-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:bdded35426210faeca8da11e8b4a54e60ccc0c1a832660d76587b5be133b0f55", size = 4104073, upload-time = "2025-08-21T05:16:23.819Z" },
{ url = "https://files.pythonhosted.org/packages/f2/4c/7a831c9c6e609692953db677f54788bd1dde4c9d34e6ba91f1e153d2e7fe/kuzu-0.11.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6116b609aac153f3523130b31295643d34a6c9509914c0fa9d804b26b23eee73", size = 6212263, upload-time = "2025-08-21T05:16:25.351Z" },
{ url = "https://files.pythonhosted.org/packages/47/95/615ef10b46b22ec1d33fdbba795e6e79733d9a244aabdeeb910f267ab36c/kuzu-0.11.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09da5b8cb24dc6b281a6e4ac0f7f24226eb9909803b187e02d014da13ba57bcf", size = 6992492, upload-time = "2025-08-21T05:16:27.518Z" },
{ url = "https://files.pythonhosted.org/packages/a7/dd/2c905575913c743e6c67a5ca89a6b4ea9d9737238966d85d7e710f0d3e60/kuzu-0.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:c663fb84682f8ebffbe7447a4e552a0e03bd29097d319084a2c53c2e032a780e", size = 4305267, upload-time = "2025-08-21T05:16:29.307Z" },
{ url = "https://files.pythonhosted.org/packages/89/05/44fbfc9055dba3f472ea4aaa8110635864d3441eede987526ef401680765/kuzu-0.11.2-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c03fb95ffb9185c1519333f8ee92b7a9695aa7aa9a179e868a7d7bd13d10a16", size = 6216795, upload-time = "2025-08-21T05:16:30.944Z" },
{ url = "https://files.pythonhosted.org/packages/4f/ca/16c81dc68cc1e8918f8481e7ee89c28aa665c5cb36be7ad0fc1d0d295760/kuzu-0.11.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d857f0efddf26d5e2dc189facb84bf04a997e395972486669b418a470cc76034", size = 6996333, upload-time = "2025-08-21T05:16:32.568Z" },
{ url = "https://files.pythonhosted.org/packages/48/d8/9275c7e6312bd76dc670e8e2da68639757c22cf2c366e96527595a1d881c/kuzu-0.11.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb9e4641867c35b98ceaa604aa79832c0eeed41f5fd1b6da22b1c217b2f1b8ea", size = 6212202, upload-time = "2025-08-21T05:16:34.571Z" },
{ url = "https://files.pythonhosted.org/packages/88/89/67a977493c60bca3610845df13020711f357a5d80bf91549e4b48d877c2f/kuzu-0.11.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553408d76a0b4fdecc1338b69b71d7bde42f6936d3b99d9852b30d33bda15978", size = 6992264, upload-time = "2025-08-21T05:16:36.316Z" },
{ url = "https://files.pythonhosted.org/packages/b6/49/869ceceb1d8a5ea032a35c734e55cfee919340889973623096da7eb94f6b/kuzu-0.11.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989a87fa13ffa39ab7773d968fe739ac4f8faf9ddb5dad72ced2eeef12180293", size = 6216814, upload-time = "2025-08-21T05:16:38.348Z" },
{ url = "https://files.pythonhosted.org/packages/bc/cd/933b34a246edb882a042eb402747167719222c05149b73b48ba7d310d554/kuzu-0.11.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e67420d04a9643fd6376a23b17b398a3e32bb0c2bd8abbf8d1e4697056596c7e", size = 6996343, upload-time = "2025-08-21T05:16:39.973Z" },
{ url = "https://files.pythonhosted.org/packages/f5/3d/830489670618ceb6094b6ddc322e3e6457f5cf4fd6916526b7b8cd6e2c1f/kuzu-0.11.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3d93131f3dc7b647da7a5124c975dc2cc207afc38a9fbb83badc23d2e25dbfec", size = 4093610, upload-time = "2025-10-10T13:35:47.691Z" },
{ url = "https://files.pythonhosted.org/packages/82/1c/7cf246a66a287d466c6cc2f01d5f4e12bd6d23350217c592dc6b51988ed5/kuzu-0.11.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:4f021a6b4e31867a0b49e369431c8f05ef4244cea1cb337c76114649975f56e3", size = 4517385, upload-time = "2025-10-10T13:35:49.471Z" },
{ url = "https://files.pythonhosted.org/packages/d6/35/ed37f146225167ed7a8573a09e2ee4ebafd0111b815cb0532dc823069729/kuzu-0.11.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ac7d2a81d7370dc12400431a3331c45954340b96439fcf2b730794cf670684a", size = 6795559, upload-time = "2025-10-10T13:35:50.977Z" },
{ url = "https://files.pythonhosted.org/packages/03/9f/2c8e3cf777aba73d515f73c9491ba65fbebb7852f41abedfc70a26bec229/kuzu-0.11.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8621bb470390f95810c7e79e36a670e9a2f27e189ef429f3df892626de63a652", size = 7616362, upload-time = "2025-10-10T13:35:52.717Z" },
{ url = "https://files.pythonhosted.org/packages/fb/02/22789dc00abb34206e6d96b0ae0eb1884b524fb7fdffd5121fc3178a9ed6/kuzu-0.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:126efba7f8a504614f5b307bcb94ac0e6d9f87f7e34b4334ca769ad6cfe2215e", size = 4712323, upload-time = "2025-10-10T13:35:54.44Z" },
{ url = "https://files.pythonhosted.org/packages/46/1b/65d3974551f10d100ca4682b1e4beff23a9c5b7555c6ea552a3855555cc0/kuzu-0.11.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:836739dced9f61912a80bb7ad1df2159cef456c5b5cfe92f15394b9c51a785cb", size = 4094223, upload-time = "2025-10-10T13:35:56.023Z" },
{ url = "https://files.pythonhosted.org/packages/a9/e8/0efbc4812796468ca47273fc53c21c63706bc5f7bc4fa3459918d323ced8/kuzu-0.11.3-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:8d4f0e4085d3a85b0e7a8e337082bec6a3cf8c92c9a35209ffe53b2ed212ab08", size = 4519024, upload-time = "2025-10-10T13:35:57.665Z" },
{ url = "https://files.pythonhosted.org/packages/dd/b2/07e81d9f1858a592d1ddc1f02a483718cdfac3315bbca019b13b2ddd8c3e/kuzu-0.11.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1419ada227d15107c2b2536c66ae715c59876585d434b1918c17598956dcd5f7", size = 6796096, upload-time = "2025-10-10T13:35:59.174Z" },
{ url = "https://files.pythonhosted.org/packages/b1/e0/8ea0d289ef6840fbd00e642657ed07d03690a97a01676e2b79d5c3e9ddf8/kuzu-0.11.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef094001d319804fcc8eb72775a184f1119d84af1bace29581a003bd806c36cd", size = 7616892, upload-time = "2025-10-10T13:36:00.866Z" },
{ url = "https://files.pythonhosted.org/packages/a3/d6/9ea65a74c9140e13d7f68dd9d8f95f42b55b9d7750e7a20df3d9b2f09734/kuzu-0.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:eb0858ec8084b10badeae37e730fbe0c3b2846dfe3508001d123087de262efbb", size = 4712696, upload-time = "2025-10-10T13:36:02.607Z" },
{ url = "https://files.pythonhosted.org/packages/64/88/ed193fd0ddfdbdde6c79e96b96df3b760fe48b2626e7151d81a1ed90fd9f/kuzu-0.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d865ca31506867cf1ccf50c094c44de96de94bc77ffb350bfcaca0e4c5e469da", size = 4093637, upload-time = "2025-10-10T13:36:04.206Z" },
{ url = "https://files.pythonhosted.org/packages/d6/6d/06e02828b78297d6d99ff3dfb0ab7b5ec5d075053aae33b53189437bbb66/kuzu-0.11.3-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:109372bc16ce6724f88e0312bc686e34145e330d69b163b22ba92f4d3d96b48f", size = 4520482, upload-time = "2025-10-10T13:36:06.302Z" },
{ url = "https://files.pythonhosted.org/packages/72/d5/0939a953860a8b373bef7b8a66a4571b27ff9faeb22672d2cd2cf3b6ba15/kuzu-0.11.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6274da6c470c001b7d332ec78a076395b009c2f267914640884fd6fa78bf47d", size = 6795398, upload-time = "2025-10-10T13:36:08Z" },
{ url = "https://files.pythonhosted.org/packages/7d/5d/8e3dfb89aa3f70f63aa283c523f2dd2ac90a1b3ed990643e3a89909236f9/kuzu-0.11.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bb3b833ca2d1d919423cb3e0150592c2587562ab85259277f622e6f06e0b487", size = 7615389, upload-time = "2025-10-10T13:36:09.809Z" },
{ url = "https://files.pythonhosted.org/packages/6c/19/c8e93185d6142f01b2e6daec4ad537dfd32afd1f69894889769b725b08c1/kuzu-0.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:605909f744763775b8647014a03526d7f928a7b5a62a8b8c1d1e7bbdaf9dbb6c", size = 4714355, upload-time = "2025-10-10T13:36:11.527Z" },
{ url = "https://files.pythonhosted.org/packages/c9/e4/2c0e222a9b0605745234fec2774a25dd2e472699931f683f15d28ab8c076/kuzu-0.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e20ab3e3b20ccf75219872feb86582f959e313eeb59f51131adf4c91ebfabe30", size = 4093664, upload-time = "2025-10-10T13:36:13.116Z" },
{ url = "https://files.pythonhosted.org/packages/88/05/3020ed9a0a7b492597f211f805233b77ef37266a23c27efc40bb7cb37402/kuzu-0.11.3-cp313-cp313-macosx_11_0_x86_64.whl", hash = "sha256:054479d3ce71410b8af2f5fa6aa37883db7fea5b25606af8d3bd7cf717aa5395", size = 4520498, upload-time = "2025-10-10T13:36:14.933Z" },
{ url = "https://files.pythonhosted.org/packages/0f/66/1a502700a7f2863f8f60621a412a7074d7eda9e92f18fd1d8d86905aa4d3/kuzu-0.11.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:143a37f1ae38b6b4337ccfcf42fa4f779a897223fff9c6c29f1a5a5a86911300", size = 6795804, upload-time = "2025-10-10T13:36:16.55Z" },
{ url = "https://files.pythonhosted.org/packages/79/c2/1ea8cdc05946cb5906a7ebb451d7268e501ebb51ebecc0437969f8c07450/kuzu-0.11.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:548bfb3045d89bce1fbe89f4a890d636789671abfa80cbde2054c671e6069133", size = 7615668, upload-time = "2025-10-10T13:36:18.882Z" },
{ url = "https://files.pythonhosted.org/packages/d1/c3/336d6181f8f50126cf3d7186b3c5479f9f49d973145f79bed45cf87a9bb7/kuzu-0.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:87bf6c369f182a59e5b8a38b3ca288b90fab2827577d9b0d2170a202c42bc8f5", size = 4714372, upload-time = "2025-10-10T13:36:20.877Z" },
{ url = "https://files.pythonhosted.org/packages/94/db/e7e6cada6dc924eb8939bd35c5f724f5de4fc430a64d6d9e71b75cd0c271/kuzu-0.11.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb5c165bc5838059e498e8325939fc6bac075e1941157e8df6ebdd710135d43b", size = 6798556, upload-time = "2025-10-10T13:36:22.472Z" },
{ url = "https://files.pythonhosted.org/packages/cf/68/a0fa02134cb255c80b5ed5bb5f6130fbbc75a8ae8be4fd6ea6eb6bc8014b/kuzu-0.11.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88c73dfd3d6a1fb374031050b725236fa9dd9a95424b09b20086a3d274bed51f", size = 7620378, upload-time = "2025-10-10T13:36:24.453Z" },
{ url = "https://files.pythonhosted.org/packages/d6/b7/2a4569984995f09476dbf1ef2e0a7298aa9fdb8896f2e8195d80e11786f4/kuzu-0.11.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d2752a9e37adda6aef3bf041932ae3a1cf74ca7e893bbbacdd5e62b3ac6f8c2", size = 6795649, upload-time = "2025-10-10T13:36:26.15Z" },
{ url = "https://files.pythonhosted.org/packages/77/13/df6e06a7d7506743c3a6cfbe50ee3f9d3fc58228e2a2fcbe7e74e7c17b00/kuzu-0.11.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86be7d113e4e2c6761b1701079af8aeffc04c6981517f2d6aa393e883cc46036", size = 7615882, upload-time = "2025-10-10T13:36:28.215Z" },
{ url = "https://files.pythonhosted.org/packages/32/85/c52c3b167edcc67da3b8788a20a2fb5b4f045060cbe1aed6121ce3ce83d3/kuzu-0.11.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d72ebd88e231b562e7a60ff88d200825d53e78a681bddd7f8d77b78126a5060c", size = 6798657, upload-time = "2025-10-10T13:36:29.935Z" },
{ url = "https://files.pythonhosted.org/packages/06/be/5b4ff168718165c2ff5848ab79e22ecce72ad00522afee6820d390cb0753/kuzu-0.11.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64c7ec822906bdee154eb38d93e64f184d8f94b30bbeaceaa252725f2b9efab3", size = 7620394, upload-time = "2025-10-10T13:36:31.69Z" },
]
[[package]]
@ -1094,8 +1115,7 @@ version = "1.0.0rc0"
source = { virtual = "." }
dependencies = [
{ name = "azure-identity" },
{ name = "graphiti-core" },
{ name = "kuzu" },
{ name = "graphiti-core", extra = ["falkordb", "kuzu"] },
{ name = "mcp" },
{ name = "openai" },
{ name = "pydantic-settings" },
@ -1134,11 +1154,10 @@ requires-dist = [
{ name = "anthropic", marker = "extra == 'providers'", specifier = ">=0.49.0" },
{ name = "azure-identity", specifier = ">=1.21.0" },
{ name = "google-genai", marker = "extra == 'providers'", specifier = ">=1.8.0" },
{ name = "graphiti-core", editable = "../" },
{ name = "graphiti-core", marker = "extra == 'dev'", editable = "../" },
{ name = "graphiti-core", extras = ["kuzu", "falkordb"], editable = "../" },
{ name = "groq", marker = "extra == 'providers'", specifier = ">=0.2.0" },
{ name = "httpx", marker = "extra == 'dev'", specifier = ">=0.28.1" },
{ name = "kuzu", specifier = ">=0.11.2" },
{ name = "mcp", specifier = ">=1.9.4" },
{ name = "mcp", marker = "extra == 'dev'", specifier = ">=1.9.4" },
{ name = "openai", specifier = ">=1.91.0" },
@ -2186,6 +2205,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
]
[[package]]
name = "redis"
version = "5.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "async-timeout", marker = "python_full_version < '3.11.3'" },
{ name = "pyjwt" },
]
sdist = { url = "https://files.pythonhosted.org/packages/6a/cf/128b1b6d7086200c9f387bd4be9b2572a30b90745ef078bd8b235042dc9f/redis-5.3.1.tar.gz", hash = "sha256:ca49577a531ea64039b5a36db3d6cd1a0c7a60c34124d46924a45b956e8cf14c", size = 4626200, upload-time = "2025-07-25T08:06:27.778Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/26/5c5fa0e83c3621db835cfc1f1d789b37e7fa99ed54423b5f519beb931aa7/redis-5.3.1-py3-none-any.whl", hash = "sha256:dc1909bd24669cc31b5f67a039700b16ec30571096c5f1f0d9d2324bff31af97", size = 272833, upload-time = "2025-07-25T08:06:26.317Z" },
]
[[package]]
name = "regex"
version = "2025.7.34"