Add MCP Server (#301)
* experimental * experimental * experimental * wip * wip * wip * wip * code cleanup * refactor and cleanup * fix lint * remove unneeded mcp dep * polish
This commit is contained in:
parent
4e52c57675
commit
4307274967
15 changed files with 2778 additions and 1010 deletions
18
README.md
18
README.md
|
|
@ -187,6 +187,22 @@ The `server` directory contains an API service for interacting with the Graphiti
|
|||
|
||||
Please see the [server README](./server/README.md) for more information.
|
||||
|
||||
## MCP Server
|
||||
|
||||
The `mcp_server` directory contains a Model Context Protocol (MCP) server implementation for Graphiti. This server allows AI assistants to interact with Graphiti's knowledge graph capabilities through the MCP protocol.
|
||||
|
||||
Key features of the MCP server include:
|
||||
|
||||
- Episode management (add, retrieve, delete)
|
||||
- Entity management and relationship handling
|
||||
- Semantic and hybrid search capabilities
|
||||
- Group management for organizing related data
|
||||
- Graph maintenance operations
|
||||
|
||||
The MCP server can be deployed using Docker with Neo4j, making it easy to integrate Graphiti into your AI assistant workflows.
|
||||
|
||||
For detailed setup instructions and usage examples, see the [MCP server README](./mcp_server/README.md).
|
||||
|
||||
## Optional Environment Variables
|
||||
|
||||
In addition to the Neo4j and OpenAi-compatible credentials, Graphiti also has a few optional environment variables.
|
||||
|
|
@ -260,7 +276,7 @@ Graphiti is under active development. We aim to maintain API stability while wor
|
|||
- Allow developers to provide their own defined node and edge classes when ingesting episodes
|
||||
- Enable more flexible knowledge representation tailored to specific use cases
|
||||
- [x] Enhancing retrieval capabilities with more robust and configurable options
|
||||
- [ ] Graphiti MCP Server
|
||||
- [x] Graphiti MCP Server
|
||||
- [ ] Expanding test coverage to ensure reliability and catch edge cases
|
||||
|
||||
## Contributing
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from .errors import RateLimitError
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_MODEL = 'claude-3-5-sonnet-20240620'
|
||||
DEFAULT_MODEL = 'claude-3-7-sonnet-latest'
|
||||
DEFAULT_MAX_TOKENS = 8192
|
||||
|
||||
|
||||
|
|
@ -58,11 +58,14 @@ class AnthropicClient(LLMClient):
|
|||
{'role': 'assistant', 'content': '{'}
|
||||
]
|
||||
|
||||
# Ensure max_tokens is not greater than config.max_tokens or DEFAULT_MAX_TOKENS
|
||||
max_tokens = min(max_tokens, self.config.max_tokens, DEFAULT_MAX_TOKENS)
|
||||
|
||||
try:
|
||||
result = await self.client.messages.create(
|
||||
system='Only include JSON in the response. Do not include any additional text or explanation of the content.\n'
|
||||
+ system_message.content,
|
||||
max_tokens=max_tokens or self.max_tokens,
|
||||
max_tokens=max_tokens,
|
||||
temperature=self.temperature,
|
||||
messages=user_messages, # type: ignore
|
||||
model=self.model or DEFAULT_MODEL,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,11 @@ class LLMClient(ABC):
|
|||
self.temperature = config.temperature
|
||||
self.max_tokens = config.max_tokens
|
||||
self.cache_enabled = cache
|
||||
self.cache_dir = Cache(DEFAULT_CACHE_DIR) # Create a cache directory
|
||||
self.cache_dir = None
|
||||
|
||||
# Only create the cache directory if caching is enabled
|
||||
if self.cache_enabled:
|
||||
self.cache_dir = Cache(DEFAULT_CACHE_DIR)
|
||||
|
||||
def _clean_input(self, input: str) -> str:
|
||||
"""Clean input string of invalid unicode and control characters.
|
||||
|
|
@ -129,7 +133,7 @@ class LLMClient(ABC):
|
|||
f'\n\nRespond with a JSON object in the following format:\n\n{serialized_model}'
|
||||
)
|
||||
|
||||
if self.cache_enabled:
|
||||
if self.cache_enabled and self.cache_dir is not None:
|
||||
cache_key = self._get_cache_key(messages)
|
||||
|
||||
cached_response = self.cache_dir.get(cache_key)
|
||||
|
|
@ -142,7 +146,8 @@ class LLMClient(ABC):
|
|||
|
||||
response = await self._generate_response_with_retry(messages, response_model, max_tokens)
|
||||
|
||||
if self.cache_enabled:
|
||||
if self.cache_enabled and self.cache_dir is not None:
|
||||
cache_key = self._get_cache_key(messages)
|
||||
self.cache_dir.set(cache_key, response)
|
||||
|
||||
return response
|
||||
|
|
|
|||
26
mcp_server/.env.example
Normal file
26
mcp_server/.env.example
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Graphiti MCP Server Environment Configuration
|
||||
|
||||
# Neo4j Database Configuration
|
||||
# These settings are used to connect to your Neo4j database
|
||||
NEO4J_URI=bolt://localhost:7687
|
||||
NEO4J_USER=neo4j
|
||||
NEO4J_PASSWORD=demodemo
|
||||
|
||||
# OpenAI API Configuration
|
||||
# Required for LLM operations
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
MODEL_NAME=gpt-4o
|
||||
|
||||
# Optional: Only needed for non-standard OpenAI endpoints
|
||||
# OPENAI_BASE_URL=https://api.openai.com/v1
|
||||
|
||||
# Optional: Group ID for namespacing graph data
|
||||
# GROUP_ID=my_project
|
||||
|
||||
# Optional: Path configuration for Docker
|
||||
# PATH=/root/.local/bin:${PATH}
|
||||
|
||||
# Optional: Memory settings for Neo4j (used in Docker Compose)
|
||||
# NEO4J_server_memory_heap_initial__size=512m
|
||||
# NEO4J_server_memory_heap_max__size=1G
|
||||
# NEO4J_server_memory_pagecache_size=512m
|
||||
1
mcp_server/.python-version
Normal file
1
mcp_server/.python-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
3.10
|
||||
24
mcp_server/Dockerfile
Normal file
24
mcp_server/Dockerfile
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install uv for package management
|
||||
RUN apt-get update && apt-get install -y curl && \
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Add uv to PATH
|
||||
ENV PATH="/root/.local/bin:${PATH}"
|
||||
|
||||
# Copy pyproject.toml and install dependencies
|
||||
COPY pyproject.toml .
|
||||
RUN uv sync
|
||||
|
||||
# Copy application code
|
||||
COPY graphiti_mcp_server.py .
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Command to run the application
|
||||
CMD ["uv", "run", "graphiti_mcp_server.py"]
|
||||
261
mcp_server/README.md
Normal file
261
mcp_server/README.md
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
# Graphiti MCP Server
|
||||
|
||||
Graphiti is a framework for building and querying temporally-aware knowledge graphs, specifically tailored for AI agents operating in dynamic environments. Unlike traditional retrieval-augmented generation (RAG) methods, Graphiti continuously integrates user interactions, structured and unstructured enterprise data, and external information into a coherent, queryable graph. The framework supports incremental data updates, efficient retrieval, and precise historical queries without requiring complete graph recomputation, making it suitable for developing interactive, context-aware AI applications.
|
||||
|
||||
This is an experimental Model Context Protocol (MCP) server implementation for Graphiti. The MCP server exposes Graphiti's key functionality through the MCP protocol, allowing AI assistants to interact with Graphiti's knowledge graph capabilities.
|
||||
|
||||
## Features
|
||||
|
||||
The Graphiti MCP server exposes the following key high-level functions of Graphiti:
|
||||
|
||||
- **Episode Management**: Add, retrieve, and delete episodes (text, messages, or JSON data)
|
||||
- **Entity Management**: Search and manage entity nodes and relationships in the knowledge graph
|
||||
- **Search Capabilities**: Search for facts (edges) and node summaries using semantic and hybrid search
|
||||
- **Group Management**: Organize and manage groups of related data with group_id filtering
|
||||
- **Graph Maintenance**: Clear the graph and rebuild indices
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. Ensure you have Python 3.10 or higher installed.
|
||||
2. A running Neo4j database (version 5.26 or later required)
|
||||
3. OpenAI API key for LLM operations
|
||||
|
||||
### Setup
|
||||
|
||||
1. Clone the repository and navigate to the mcp_server directory
|
||||
2. Use `uv` to create a virtual environment and install dependencies:
|
||||
|
||||
```bash
|
||||
# Install uv if you don't have it already
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# Create a virtual environment and install dependencies in one step
|
||||
uv sync
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The server uses the following environment variables:
|
||||
|
||||
- `NEO4J_URI`: URI for the Neo4j database (default: `bolt://localhost:7687`)
|
||||
- `NEO4J_USER`: Neo4j username (default: `neo4j`)
|
||||
- `NEO4J_PASSWORD`: Neo4j password (default: `demodemo`)
|
||||
- `OPENAI_API_KEY`: OpenAI API key (required for LLM operations)
|
||||
- `OPENAI_BASE_URL`: Optional base URL for OpenAI API
|
||||
- `MODEL_NAME`: Optional model name to use for LLM inference
|
||||
|
||||
You can set these variables in a `.env` file in the project directory.
|
||||
|
||||
## Running the Server
|
||||
|
||||
To run the Graphiti MCP server directly using `uv`:
|
||||
|
||||
```bash
|
||||
uv run graphiti_mcp_server.py
|
||||
```
|
||||
|
||||
With options:
|
||||
|
||||
```bash
|
||||
uv run graphiti_mcp_server.py --model gpt-4o --transport sse
|
||||
```
|
||||
|
||||
Available arguments:
|
||||
|
||||
- `--model`: Specify the model name to use with the LLM client
|
||||
- `--transport`: Choose the transport method (sse or stdio, default: sse)
|
||||
- `--group-id`: Set a namespace for the graph (optional)
|
||||
- `--destroy-graph`: Destroy all Graphiti graphs (use with caution)
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
The Graphiti MCP server can be deployed using Docker. The Dockerfile uses `uv` for package management, ensuring consistent dependency installation.
|
||||
|
||||
#### Environment Configuration
|
||||
|
||||
Before running the Docker Compose setup, you need to configure the environment variables. You have two options:
|
||||
|
||||
1. **Using a .env file** (recommended):
|
||||
|
||||
- Copy the provided `.env.example` file to create a `.env` file:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
- Edit the `.env` file to set your OpenAI API key and other configuration options:
|
||||
```
|
||||
# Required for LLM operations
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
MODEL_NAME=gpt-4o
|
||||
# Optional: OPENAI_BASE_URL only needed for non-standard OpenAI endpoints
|
||||
# OPENAI_BASE_URL=https://api.openai.com/v1
|
||||
```
|
||||
- The Docker Compose setup is configured to use this file if it exists (it's optional)
|
||||
|
||||
2. **Using environment variables directly**:
|
||||
- You can also set the environment variables when running the Docker Compose command:
|
||||
```bash
|
||||
OPENAI_API_KEY=your_key MODEL_NAME=gpt-4o docker compose up
|
||||
```
|
||||
|
||||
#### Neo4j Configuration
|
||||
|
||||
The Docker Compose setup includes a Neo4j container with the following default configuration:
|
||||
|
||||
- Username: `neo4j`
|
||||
- Password: `demodemo`
|
||||
- URI: `bolt://neo4j:7687` (from within the Docker network)
|
||||
- Memory settings optimized for development use
|
||||
|
||||
#### Running with Docker Compose
|
||||
|
||||
Start the services using Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Or if you're using an older version of Docker Compose:
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
This will start both the Neo4j database and the Graphiti MCP server. The Docker setup:
|
||||
|
||||
- Uses `uv` for package management and running the server
|
||||
- Installs dependencies from the `pyproject.toml` file
|
||||
- Connects to the Neo4j container using the environment variables
|
||||
- Exposes the server on port 8000 for HTTP-based SSE transport
|
||||
- Includes a healthcheck for Neo4j to ensure it's fully operational before starting the MCP server
|
||||
|
||||
## Integrating with MCP Clients
|
||||
|
||||
### Configuration
|
||||
|
||||
To use the Graphiti MCP server with an MCP-compatible client, configure it to connect to the server:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"transport": "stdio",
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"run",
|
||||
"/ABSOLUTE/PATH/TO/graphiti_mcp_server.py",
|
||||
"--transport",
|
||||
"stdio"
|
||||
],
|
||||
"env": {
|
||||
"NEO4J_URI": "bolt://localhost:7687",
|
||||
"NEO4J_USER": "neo4j",
|
||||
"NEO4J_PASSWORD": "demodemo",
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}",
|
||||
"MODEL_NAME": "gpt-4o"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For SSE transport (HTTP-based), you can use this configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"transport": "sse",
|
||||
"url": "http://localhost:8000/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or start the server with uv and connect to it:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"run",
|
||||
"/ABSOLUTE/PATH/TO/graphiti_mcp_server.py",
|
||||
"--transport",
|
||||
"sse"
|
||||
],
|
||||
"env": {
|
||||
"NEO4J_URI": "bolt://localhost:7687",
|
||||
"NEO4J_USER": "neo4j",
|
||||
"NEO4J_PASSWORD": "demodemo",
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}",
|
||||
"MODEL_NAME": "gpt-4o"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
||||
The Graphiti MCP server exposes the following tools:
|
||||
|
||||
- `add_episode`: Add an episode to the knowledge graph (supports text, JSON, and message formats)
|
||||
- `search_nodes`: Search the knowledge graph for relevant node summaries
|
||||
- `search_facts`: Search the knowledge graph for relevant facts (edges between entities)
|
||||
- `delete_entity_edge`: Delete an entity edge from the knowledge graph
|
||||
- `delete_episode`: Delete an episode from the knowledge graph
|
||||
- `get_entity_edge`: Get an entity edge by its UUID
|
||||
- `get_episodes`: Get the most recent episodes for a specific group
|
||||
- `clear_graph`: Clear all data from the knowledge graph and rebuild indices
|
||||
- `get_status`: Get the status of the Graphiti MCP server and Neo4j connection
|
||||
|
||||
## Working with JSON Data
|
||||
|
||||
The Graphiti MCP server can process structured JSON data through the `add_episode` tool with `source="json"`. This allows you to automatically extract entities and relationships from structured data:
|
||||
|
||||
```
|
||||
add_episode(
|
||||
name="Customer Profile",
|
||||
episode_body="{\"company\": {\"name\": \"Acme Technologies\"}, \"products\": [{\"id\": \"P001\", \"name\": \"CloudSync\"}, {\"id\": \"P002\", \"name\": \"DataMiner\"}]}",
|
||||
source="json",
|
||||
source_description="CRM data"
|
||||
)
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
Once the Graphiti MCP server is running and configured with an MCP-compatible client:
|
||||
|
||||
```
|
||||
User: Add information about a company to the knowledge graph.
|
||||
|
||||
Assistant: I'll help you add information about a company to the knowledge graph.
|
||||
|
||||
[Assistant uses the add_episode tool to add the information]
|
||||
|
||||
User: Now search for information about this company.
|
||||
|
||||
Assistant: I'll search the knowledge graph for information about the company.
|
||||
|
||||
[Assistant uses the search_facts tool to find relevant facts]
|
||||
|
||||
User: Can you show me a summary of entities related to this company?
|
||||
|
||||
Assistant: I'll search for node summaries related to the company.
|
||||
|
||||
[Assistant uses the search_nodes tool to find relevant entity summaries]
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.10 or higher
|
||||
- Neo4j database (version 5.26 or later required)
|
||||
- OpenAI API key (for LLM operations)
|
||||
- MCP-compatible client
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the same license as the Graphiti project.
|
||||
46
mcp_server/docker-compose.yml
Normal file
46
mcp_server/docker-compose.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
services:
|
||||
neo4j:
|
||||
image: neo4j:5.26.0
|
||||
ports:
|
||||
- "7474:7474" # HTTP
|
||||
- "7687:7687" # Bolt
|
||||
environment:
|
||||
- NEO4J_AUTH=neo4j/demodemo
|
||||
- NEO4J_server_memory_heap_initial__size=512m
|
||||
- NEO4J_server_memory_heap_max__size=1G
|
||||
- NEO4J_server_memory_pagecache_size=512m
|
||||
volumes:
|
||||
- neo4j_data:/data
|
||||
- neo4j_logs:/logs
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-O", "/dev/null", "http://localhost:7474"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
graphiti-mcp:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false # Makes the file optional. Default value is 'true'
|
||||
depends_on:
|
||||
neo4j:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- NEO4J_URI=bolt://neo4j:7687
|
||||
- NEO4J_USER=neo4j
|
||||
- NEO4J_PASSWORD=demodemo
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- OPENAI_BASE_URL=${OPENAI_BASE_URL}
|
||||
- MODEL_NAME=${MODEL_NAME}
|
||||
- PATH=/root/.local/bin:${PATH}
|
||||
ports:
|
||||
- "8000:8000" # Expose the MCP server via HTTP for SSE transport
|
||||
command: ["uv", "run", "graphiti_mcp_server.py", "--transport", "sse"]
|
||||
|
||||
volumes:
|
||||
neo4j_data:
|
||||
neo4j_logs:
|
||||
763
mcp_server/graphiti_mcp_server.py
Normal file
763
mcp_server/graphiti_mcp_server.py
Normal file
|
|
@ -0,0 +1,763 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Graphiti MCP Server - Exposes Graphiti functionality through the Model Context Protocol (MCP)
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
from collections.abc import Awaitable, Callable
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Optional, TypedDict, TypeVar, Union, cast
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from pydantic import BaseModel
|
||||
|
||||
# graphiti_core imports
|
||||
from graphiti_core import Graphiti
|
||||
from graphiti_core.edges import EntityEdge
|
||||
from graphiti_core.llm_client import LLMClient
|
||||
from graphiti_core.llm_client.config import LLMConfig
|
||||
from graphiti_core.llm_client.openai_client import OpenAIClient
|
||||
from graphiti_core.nodes import EpisodeType, EpisodicNode
|
||||
from graphiti_core.search.search_config_recipes import NODE_HYBRID_SEARCH_RRF
|
||||
from graphiti_core.search.search_filters import SearchFilters
|
||||
from graphiti_core.utils.maintenance.graph_data_operations import clear_data
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
# Type definitions for API responses
|
||||
class ErrorResponse(TypedDict):
|
||||
error: str
|
||||
|
||||
|
||||
class SuccessResponse(TypedDict):
|
||||
message: str
|
||||
|
||||
|
||||
class NodeResult(TypedDict):
|
||||
uuid: str
|
||||
name: str
|
||||
summary: str
|
||||
labels: list[str]
|
||||
group_id: str
|
||||
created_at: str
|
||||
attributes: dict[str, Any]
|
||||
|
||||
|
||||
class NodeSearchResponse(TypedDict):
|
||||
message: str
|
||||
nodes: list[NodeResult]
|
||||
|
||||
|
||||
class FactSearchResponse(TypedDict):
|
||||
message: str
|
||||
facts: list[dict[str, Any]]
|
||||
|
||||
|
||||
class EpisodeSearchResponse(TypedDict):
|
||||
message: str
|
||||
episodes: list[dict[str, Any]]
|
||||
|
||||
|
||||
class StatusResponse(TypedDict):
|
||||
status: str
|
||||
message: str
|
||||
|
||||
|
||||
# Server configuration classes
|
||||
class GraphitiConfig(BaseModel):
|
||||
"""Configuration for Graphiti client.
|
||||
|
||||
Centralizes all configuration parameters for the Graphiti client,
|
||||
including database connection details and LLM settings.
|
||||
"""
|
||||
|
||||
neo4j_uri: str = 'bolt://localhost:7687'
|
||||
neo4j_user: str = 'neo4j'
|
||||
neo4j_password: str = 'password'
|
||||
openai_api_key: Optional[str] = None
|
||||
openai_base_url: Optional[str] = None
|
||||
model_name: Optional[str] = None
|
||||
group_id: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def from_env(cls) -> 'GraphitiConfig':
|
||||
"""Create a configuration instance from environment variables."""
|
||||
return cls(
|
||||
neo4j_uri=os.environ.get('NEO4J_URI', 'bolt://localhost:7687'),
|
||||
neo4j_user=os.environ.get('NEO4J_USER', 'neo4j'),
|
||||
neo4j_password=os.environ.get('NEO4J_PASSWORD', 'password'),
|
||||
openai_api_key=os.environ.get('OPENAI_API_KEY'),
|
||||
openai_base_url=os.environ.get('OPENAI_BASE_URL'),
|
||||
model_name=os.environ.get('MODEL_NAME'),
|
||||
)
|
||||
|
||||
|
||||
class MCPConfig(BaseModel):
|
||||
"""Configuration for MCP server."""
|
||||
|
||||
transport: str
|
||||
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
stream=sys.stderr,
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create global config instance
|
||||
config = GraphitiConfig.from_env()
|
||||
|
||||
# MCP server instructions
|
||||
GRAPHITI_MCP_INSTRUCTIONS = """
|
||||
Welcome to Graphiti MCP - a memory service for AI agents built on a knowledge graph. Graphiti performs well
|
||||
with dynamic data such as user interactions, changing enterprise data, and external information.
|
||||
|
||||
Graphiti transforms information into a richly connected knowledge network, allowing you to
|
||||
capture relationships between concepts, entities, and information. The system organizes data as episodes
|
||||
(content snippets), nodes (entities), and facts (relationships between entities), creating a dynamic,
|
||||
queryable memory store that evolves with new information. Graphiti supports multiple data formats, including
|
||||
structured JSON data, enabling seamless integration with existing data pipelines and systems.
|
||||
|
||||
Facts contain temporal metadata, allowing you to track the time of creation and whether a fact is invalid
|
||||
(superseded by new information).
|
||||
|
||||
Key capabilities:
|
||||
1. Add episodes (text, messages, or JSON) to the knowledge graph with the add_episode tool
|
||||
2. Search for nodes (entities) in the graph using natural language queries with search_nodes
|
||||
3. Find relevant facts (relationships between entities) with search_facts
|
||||
4. Retrieve specific entity edges or episodes by UUID
|
||||
5. Manage the knowledge graph with tools like delete_episode, delete_entity_edge, and clear_graph
|
||||
|
||||
The server connects to a database for persistent storage and uses language models for certain operations.
|
||||
Each piece of information is organized by group_id, allowing you to maintain separate knowledge domains.
|
||||
|
||||
When adding information, provide descriptive names and detailed content to improve search quality.
|
||||
When searching, use specific queries and consider filtering by group_id for more relevant results.
|
||||
|
||||
For optimal performance, ensure the database is properly configured and accessible, and valid
|
||||
API keys are provided for any language model operations.
|
||||
"""
|
||||
|
||||
|
||||
# MCP server instance
|
||||
mcp = FastMCP(
|
||||
'graphiti',
|
||||
instructions=GRAPHITI_MCP_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
|
||||
# Initialize Graphiti client
|
||||
graphiti_client: Optional[Graphiti] = None
|
||||
|
||||
# Type for functions that can be wrapped with graphiti_error_handler
|
||||
T = TypeVar('T')
|
||||
GraphitiFunc = Callable[..., Awaitable[T]]
|
||||
|
||||
|
||||
# Note: We've removed the error handler decorator in favor of inline error handling
|
||||
# This is to avoid type checking issues with the global graphiti_client variable
|
||||
|
||||
|
||||
async def initialize_graphiti(llm_client: Optional[LLMClient] = None, destroy_graph: bool = False):
|
||||
"""Initialize the Graphiti client with the provided settings.
|
||||
|
||||
Args:
|
||||
llm_client: Optional LLMClient instance to use for LLM operations
|
||||
destroy_graph: Optional boolean to destroy all Graphiti graphs
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
# If no client is provided, create a default OpenAI client
|
||||
if not llm_client:
|
||||
if config.openai_api_key:
|
||||
llm_config = LLMConfig(api_key=config.openai_api_key)
|
||||
if config.openai_base_url:
|
||||
llm_config.base_url = config.openai_base_url
|
||||
if config.model_name:
|
||||
llm_config.model = config.model_name
|
||||
llm_client = OpenAIClient(config=llm_config)
|
||||
logger.info('Using OpenAI as LLM client')
|
||||
else:
|
||||
raise ValueError('OPENAI_API_KEY must be set when not using a custom LLM client')
|
||||
|
||||
if not config.neo4j_uri or not config.neo4j_user or not config.neo4j_password:
|
||||
raise ValueError('NEO4J_URI, NEO4J_USER, and NEO4J_PASSWORD must be set')
|
||||
|
||||
graphiti_client = Graphiti(
|
||||
uri=config.neo4j_uri,
|
||||
user=config.neo4j_user,
|
||||
password=config.neo4j_password,
|
||||
llm_client=llm_client,
|
||||
)
|
||||
|
||||
if destroy_graph:
|
||||
logger.info('Destroying graph...')
|
||||
await clear_data(graphiti_client.driver)
|
||||
|
||||
# Initialize the graph database with Graphiti's indices
|
||||
await graphiti_client.build_indices_and_constraints()
|
||||
logger.info('Graphiti client initialized successfully')
|
||||
|
||||
|
||||
def format_fact_result(edge: EntityEdge) -> dict[str, Any]:
|
||||
"""Format an entity edge into a readable result.
|
||||
|
||||
Since EntityEdge is a Pydantic BaseModel, we can use its built-in serialization capabilities.
|
||||
|
||||
Args:
|
||||
edge: The EntityEdge to format
|
||||
|
||||
Returns:
|
||||
A dictionary representation of the edge with serialized dates and excluded embeddings
|
||||
"""
|
||||
# Convert to dict using Pydantic's model_dump method with mode='json'
|
||||
# This automatically handles datetime serialization and other complex types
|
||||
return edge.model_dump(
|
||||
mode='json', # Properly handle datetime serialization for JSON
|
||||
exclude={
|
||||
'fact_embedding', # Exclude embedding data
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def add_episode(
|
||||
name: str,
|
||||
episode_body: str,
|
||||
group_id: Optional[str] = None,
|
||||
source: str = 'text',
|
||||
source_description: str = '',
|
||||
uuid: Optional[str] = None,
|
||||
) -> Union[SuccessResponse, ErrorResponse]:
|
||||
"""Add an episode to the Graphiti knowledge graph. This is the primary way to add information to the graph.
|
||||
|
||||
Args:
|
||||
name (str): Name of the episode
|
||||
episode_body (str): The content of the episode. When source='json', this must be a properly escaped JSON string,
|
||||
not a raw Python dictionary. The JSON data will be automatically processed
|
||||
to extract entities and relationships.
|
||||
group_id (str, optional): A unique ID for this graph. If not provided, uses the default group_id from CLI
|
||||
or a generated one.
|
||||
source (str, optional): Source type, must be one of:
|
||||
- 'text': For plain text content (default)
|
||||
- 'json': For structured data
|
||||
- 'message': For conversation-style content
|
||||
source_description (str, optional): Description of the source
|
||||
uuid (str, optional): Optional UUID for the episode
|
||||
|
||||
Examples:
|
||||
# Adding plain text content
|
||||
add_episode(
|
||||
name="Company News",
|
||||
episode_body="Acme Corp announced a new product line today.",
|
||||
source="text",
|
||||
source_description="news article",
|
||||
group_id="some_arbitrary_string"
|
||||
)
|
||||
|
||||
# Adding structured JSON data
|
||||
# NOTE: episode_body must be a properly escaped JSON string
|
||||
add_episode(
|
||||
name="Customer Profile",
|
||||
episode_body="{\\\"company\\\": {\\\"name\\\": \\\"Acme Technologies\\\"}, \\\"products\\\": [{\\\"id\\\": \\\"P001\\\", \\\"name\\\": \\\"CloudSync\\\"}, {\\\"id\\\": \\\"P002\\\", \\\"name\\\": \\\"DataMiner\\\"}]}",
|
||||
source="json",
|
||||
source_description="CRM data"
|
||||
)
|
||||
|
||||
# Adding more complex JSON with arrays and nested objects
|
||||
add_episode(
|
||||
name="Product Catalog",
|
||||
episode_body='\{"catalog": \{"company": "Tech Solutions Inc.", "products": [\{"id": "P001", "name": "Product X", "features": ["Feature A", "Feature B"]\}]\}\}',
|
||||
source="json",
|
||||
source_description="Product catalog"
|
||||
)
|
||||
|
||||
# Adding message-style content
|
||||
add_episode(
|
||||
name="Customer Conversation",
|
||||
episode_body="user: What's your return policy?\nassistant: You can return items within 30 days.",
|
||||
source="message",
|
||||
source_description="chat transcript",
|
||||
group_id="some_arbitrary_string"
|
||||
)
|
||||
|
||||
Notes:
|
||||
When using source='json':
|
||||
- The JSON must be a properly escaped string, not a raw Python dictionary
|
||||
- The JSON will be automatically processed to extract entities and relationships
|
||||
- Complex nested structures are supported (arrays, nested objects, mixed data types), but keep nesting to a minimum
|
||||
- Entities will be created from appropriate JSON properties
|
||||
- Relationships between entities will be established based on the JSON structure
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# Map string source to EpisodeType enum
|
||||
source_type = EpisodeType.text
|
||||
if source.lower() == 'message':
|
||||
source_type = EpisodeType.message
|
||||
elif source.lower() == 'json':
|
||||
source_type = EpisodeType.json
|
||||
|
||||
# Use the provided group_id or fall back to the default from config
|
||||
effective_group_id = group_id if group_id is not None else config.group_id
|
||||
|
||||
# Cast group_id to str to satisfy type checker
|
||||
# The Graphiti client expects a str for group_id, not Optional[str]
|
||||
group_id_str = str(effective_group_id) if effective_group_id is not None else ''
|
||||
|
||||
# We've already checked that graphiti_client is not None above
|
||||
# This assert statement helps type checkers understand that graphiti_client is defined
|
||||
# from this point forward in the function
|
||||
assert graphiti_client is not None, 'graphiti_client should not be None here'
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
# This doesn't change the runtime behavior, only helps with static type checking
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Type checking will now know that client is a Graphiti instance (not None)
|
||||
# and group_id is a str, not Optional[str]
|
||||
await client.add_episode(
|
||||
name=name,
|
||||
episode_body=episode_body,
|
||||
source=source_type,
|
||||
source_description=source_description,
|
||||
group_id=group_id_str, # Using the string version of group_id
|
||||
uuid=uuid,
|
||||
reference_time=datetime.now(timezone.utc),
|
||||
)
|
||||
return {'message': f"Episode '{name}' added successfully"}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error adding episode: {error_msg}')
|
||||
return {'error': f'Error adding episode: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def search_nodes(
|
||||
query: str,
|
||||
group_ids: Optional[list[str]] = None,
|
||||
max_nodes: int = 10,
|
||||
center_node_uuid: Optional[str] = None,
|
||||
) -> Union[NodeSearchResponse, ErrorResponse]:
|
||||
"""Search the Graphiti knowledge graph for relevant node summaries.
|
||||
These contain a summary of all of a node's relationships with other nodes.
|
||||
|
||||
Args:
|
||||
query: The search query
|
||||
group_ids: Optional list of group IDs to filter results
|
||||
max_nodes: Maximum number of nodes to return (default: 10)
|
||||
center_node_uuid: Optional UUID of a node to center the search around
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return ErrorResponse(error='Graphiti client not initialized')
|
||||
|
||||
try:
|
||||
# Use the provided group_ids or fall back to the default from config if none provided
|
||||
effective_group_ids = (
|
||||
group_ids if group_ids is not None else [config.group_id] if config.group_id else []
|
||||
)
|
||||
|
||||
# Configure the search
|
||||
search_config = NODE_HYBRID_SEARCH_RRF.model_copy(deep=True)
|
||||
search_config.limit = max_nodes
|
||||
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Perform the search using the _search method
|
||||
search_results = await client._search(
|
||||
query=query,
|
||||
config=search_config,
|
||||
group_ids=effective_group_ids,
|
||||
center_node_uuid=center_node_uuid,
|
||||
search_filter=SearchFilters(),
|
||||
)
|
||||
|
||||
if not search_results.nodes:
|
||||
return NodeSearchResponse(message='No relevant nodes found', nodes=[])
|
||||
|
||||
# Format the node results
|
||||
formatted_nodes: list[NodeResult] = [
|
||||
{
|
||||
'uuid': node.uuid,
|
||||
'name': node.name,
|
||||
'summary': node.summary if hasattr(node, 'summary') else '',
|
||||
'labels': node.labels if hasattr(node, 'labels') else [],
|
||||
'group_id': node.group_id,
|
||||
'created_at': node.created_at.isoformat(),
|
||||
'attributes': node.attributes if hasattr(node, 'attributes') else {},
|
||||
}
|
||||
for node in search_results.nodes
|
||||
]
|
||||
|
||||
return NodeSearchResponse(message='Nodes retrieved successfully', nodes=formatted_nodes)
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error searching nodes: {error_msg}')
|
||||
return ErrorResponse(error=f'Error searching nodes: {error_msg}')
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def search_facts(
|
||||
query: str,
|
||||
group_ids: Optional[list[str]] = None,
|
||||
max_facts: int = 10,
|
||||
center_node_uuid: Optional[str] = None,
|
||||
) -> Union[FactSearchResponse, ErrorResponse]:
|
||||
"""Search the Graphiti knowledge graph for relevant facts.
|
||||
|
||||
Args:
|
||||
query: The search query
|
||||
group_ids: Optional list of group IDs to filter results
|
||||
max_facts: Maximum number of facts to return (default: 10)
|
||||
center_node_uuid: Optional UUID of a node to center the search around
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# Use the provided group_ids or fall back to the default from config if none provided
|
||||
effective_group_ids = (
|
||||
group_ids if group_ids is not None else [config.group_id] if config.group_id else []
|
||||
)
|
||||
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
relevant_edges = await client.search(
|
||||
group_ids=effective_group_ids,
|
||||
query=query,
|
||||
num_results=max_facts,
|
||||
center_node_uuid=center_node_uuid,
|
||||
)
|
||||
|
||||
if not relevant_edges:
|
||||
return {'message': 'No relevant facts found', 'facts': []}
|
||||
|
||||
facts = [format_fact_result(edge) for edge in relevant_edges]
|
||||
return {'message': 'Facts retrieved successfully', 'facts': facts}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error searching facts: {error_msg}')
|
||||
return {'error': f'Error searching facts: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_entity_edge(uuid: str) -> Union[SuccessResponse, ErrorResponse]:
|
||||
"""Delete an entity edge from the Graphiti knowledge graph.
|
||||
|
||||
Args:
|
||||
uuid: UUID of the entity edge to delete
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Get the entity edge by UUID
|
||||
entity_edge = await EntityEdge.get_by_uuid(client.driver, uuid)
|
||||
# Delete the edge using its delete method
|
||||
await entity_edge.delete(client.driver)
|
||||
return {'message': f'Entity edge with UUID {uuid} deleted successfully'}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error deleting entity edge: {error_msg}')
|
||||
return {'error': f'Error deleting entity edge: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_episode(uuid: str) -> Union[SuccessResponse, ErrorResponse]:
|
||||
"""Delete an episode from the Graphiti knowledge graph.
|
||||
|
||||
Args:
|
||||
uuid: UUID of the episode to delete
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Get the episodic node by UUID - EpisodicNode is already imported at the top
|
||||
episodic_node = await EpisodicNode.get_by_uuid(client.driver, uuid)
|
||||
# Delete the node using its delete method
|
||||
await episodic_node.delete(client.driver)
|
||||
return {'message': f'Episode with UUID {uuid} deleted successfully'}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error deleting episode: {error_msg}')
|
||||
return {'error': f'Error deleting episode: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_entity_edge(uuid: str) -> Union[dict[str, Any], ErrorResponse]:
|
||||
"""Get an entity edge from the Graphiti knowledge graph by its UUID.
|
||||
|
||||
Args:
|
||||
uuid: UUID of the entity edge to retrieve
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Get the entity edge directly using the EntityEdge class method
|
||||
entity_edge = await EntityEdge.get_by_uuid(client.driver, uuid)
|
||||
|
||||
# Use the format_fact_result function to serialize the edge
|
||||
# Return the Python dict directly - MCP will handle serialization
|
||||
return format_fact_result(entity_edge)
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error getting entity edge: {error_msg}')
|
||||
return {'error': f'Error getting entity edge: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_episodes(
|
||||
group_id: Optional[str] = None, last_n: int = 10
|
||||
) -> Union[list[dict[str, Any]], EpisodeSearchResponse, ErrorResponse]:
|
||||
"""Get the most recent episodes for a specific group.
|
||||
|
||||
Args:
|
||||
group_id: ID of the group to retrieve episodes from. If not provided, uses the default group_id.
|
||||
last_n: Number of most recent episodes to retrieve (default: 10)
|
||||
"""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# Use the provided group_id or fall back to the default from config
|
||||
effective_group_id = group_id if group_id is not None else config.group_id
|
||||
|
||||
if not isinstance(effective_group_id, str):
|
||||
return {'error': 'Group ID must be a string'}
|
||||
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
episodes = await client.retrieve_episodes(
|
||||
group_ids=[effective_group_id], last_n=last_n, reference_time=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
if not episodes:
|
||||
return {'message': f'No episodes found for group {effective_group_id}', 'episodes': []}
|
||||
|
||||
# Use Pydantic's model_dump method for EpisodicNode serialization
|
||||
formatted_episodes = [
|
||||
# Use mode='json' to handle datetime serialization
|
||||
episode.model_dump(mode='json')
|
||||
for episode in episodes
|
||||
]
|
||||
|
||||
# Return the Python list directly - MCP will handle serialization
|
||||
return formatted_episodes
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error getting episodes: {error_msg}')
|
||||
return {'error': f'Error getting episodes: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_graph() -> Union[SuccessResponse, ErrorResponse]:
|
||||
"""Clear all data from the Graphiti knowledge graph and rebuild indices."""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'error': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# clear_data is already imported at the top
|
||||
await clear_data(client.driver)
|
||||
await client.build_indices_and_constraints()
|
||||
return {'message': 'Graph cleared successfully and indices rebuilt'}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error clearing graph: {error_msg}')
|
||||
return {'error': f'Error clearing graph: {error_msg}'}
|
||||
|
||||
|
||||
@mcp.resource('http://graphiti/status')
|
||||
async def get_status() -> StatusResponse:
|
||||
"""Get the status of the Graphiti MCP server and Neo4j connection."""
|
||||
global graphiti_client
|
||||
|
||||
if graphiti_client is None:
|
||||
return {'status': 'error', 'message': 'Graphiti client not initialized'}
|
||||
|
||||
try:
|
||||
# We've already checked that graphiti_client is not None above
|
||||
assert graphiti_client is not None
|
||||
|
||||
# Use cast to help the type checker understand that graphiti_client is not None
|
||||
client = cast(Graphiti, graphiti_client)
|
||||
|
||||
# Test Neo4j connection
|
||||
await client.driver.verify_connectivity()
|
||||
return {'status': 'ok', 'message': 'Graphiti MCP server is running and connected to Neo4j'}
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
logger.error(f'Error checking Neo4j connection: {error_msg}')
|
||||
return {
|
||||
'status': 'error',
|
||||
'message': f'Graphiti MCP server is running but Neo4j connection failed: {error_msg}',
|
||||
}
|
||||
|
||||
|
||||
def create_llm_client(
|
||||
client_type: str = 'openai', api_key: Optional[str] = None, model: Optional[str] = None
|
||||
) -> LLMClient:
|
||||
"""Create an OpenAI LLM client.
|
||||
|
||||
Args:
|
||||
client_type: Type of LLM client to create (only 'openai' or 'openai_generic' supported)
|
||||
api_key: API key for the OpenAI service
|
||||
model: Model name to use
|
||||
|
||||
Returns:
|
||||
An instance of the OpenAI LLM client
|
||||
"""
|
||||
# Create config with provided API key and model
|
||||
llm_config = LLMConfig(api_key=api_key)
|
||||
|
||||
# Set model if provided
|
||||
if model:
|
||||
llm_config.model = model
|
||||
|
||||
# Create and return the client
|
||||
return OpenAIClient(config=llm_config)
|
||||
|
||||
|
||||
async def initialize_server() -> MCPConfig:
|
||||
"""Initialize the Graphiti server with the specified LLM client."""
|
||||
global config
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Run the Graphiti MCP server with optional LLM client'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--group-id',
|
||||
help='Namespace for the graph. This is an arbitrary string used to organize related data. '
|
||||
'If not provided, a random UUID will be generated.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--transport',
|
||||
choices=['sse', 'stdio'],
|
||||
default='sse',
|
||||
help='Transport to use for communication with the client. (default: sse)',
|
||||
)
|
||||
# OpenAI is the only supported LLM client
|
||||
parser.add_argument('--model', help='Model name to use with the LLM client')
|
||||
parser.add_argument('--destroy-graph', action='store_true', help='Destroy all Graphiti graphs')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Set the group_id from CLI argument or generate a random one
|
||||
if args.group_id:
|
||||
config.group_id = args.group_id
|
||||
logger.info(f'Using provided group_id: {config.group_id}')
|
||||
else:
|
||||
config.group_id = f'graph_{uuid.uuid4().hex[:8]}'
|
||||
logger.info(f'Generated random group_id: {config.group_id}')
|
||||
|
||||
llm_client = None
|
||||
|
||||
# Create OpenAI client if model is specified or if OPENAI_API_KEY is available
|
||||
if args.model or config.openai_api_key:
|
||||
# Override model from command line if specified
|
||||
if args.model:
|
||||
config.model_name = args.model
|
||||
|
||||
# Create the OpenAI client
|
||||
llm_client = create_llm_client(
|
||||
client_type='openai', api_key=config.openai_api_key, model=config.model_name
|
||||
)
|
||||
|
||||
# Initialize Graphiti with the specified LLM client
|
||||
await initialize_graphiti(llm_client, destroy_graph=args.destroy_graph)
|
||||
|
||||
return MCPConfig(transport=args.transport)
|
||||
|
||||
|
||||
async def run_mcp_server():
|
||||
"""Run the MCP server in the current event loop."""
|
||||
# Initialize the server
|
||||
mcp_config = await initialize_server()
|
||||
|
||||
# Run the server with stdio transport for MCP in the same event loop
|
||||
logger.info(f'Starting MCP server with transport: {mcp_config.transport}')
|
||||
if mcp_config.transport == 'stdio':
|
||||
await mcp.run_stdio_async()
|
||||
elif mcp_config.transport == 'sse':
|
||||
logger.info(
|
||||
f'Running MCP server with SSE transport on {mcp.settings.host}:{mcp.settings.port}'
|
||||
)
|
||||
await mcp.run_sse_async()
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to run the Graphiti MCP server."""
|
||||
try:
|
||||
# Run everything in a single event loop
|
||||
asyncio.run(run_mcp_server())
|
||||
except Exception as e:
|
||||
logger.error(f'Error initializing Graphiti MCP server: {str(e)}')
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
8
mcp_server/mcp_config_sse_example.json
Normal file
8
mcp_server/mcp_config_sse_example.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"transport": "sse",
|
||||
"url": "http://localhost:8000/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
21
mcp_server/mcp_config_stdio_example.json
Normal file
21
mcp_server/mcp_config_stdio_example.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"graphiti": {
|
||||
"transport": "stdio",
|
||||
"command": "uv",
|
||||
"args": [
|
||||
"run",
|
||||
"/ABSOLUTE/PATH/TO/graphiti_mcp_server.py",
|
||||
"--transport",
|
||||
"stdio"
|
||||
],
|
||||
"env": {
|
||||
"NEO4J_URI": "bolt://localhost:7687",
|
||||
"NEO4J_USER": "neo4j",
|
||||
"NEO4J_PASSWORD": "demodemo",
|
||||
"OPENAI_API_KEY": "${OPENAI_API_KEY}",
|
||||
"MODEL_NAME": "gpt-4o"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
mcp_server/pyproject.toml
Normal file
11
mcp_server/pyproject.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[project]
|
||||
name = "mcp-server"
|
||||
version = "0.1.0"
|
||||
description = "Graphiti MCP Server"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"mcp>=1.5.0",
|
||||
"openai>=1.68.2",
|
||||
"graphiti-core>=0.8.1",
|
||||
]
|
||||
571
mcp_server/uv.lock
generated
Normal file
571
mcp_server/uv.lock
generated
Normal file
|
|
@ -0,0 +1,571 @@
|
|||
version = 1
|
||||
requires-python = ">=3.10"
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anthropic"
|
||||
version = "0.49.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "distro" },
|
||||
{ name = "httpx" },
|
||||
{ name = "jiter" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "sniffio" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/86/e3/a88c8494ce4d1a88252b9e053607e885f9b14d0a32273d47b727cbee4228/anthropic-0.49.0.tar.gz", hash = "sha256:c09e885b0f674b9119b4f296d8508907f6cff0009bc20d5cf6b35936c40b4398", size = 210016 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/74/5d90ad14d55fbe3f9c474fdcb6e34b4bed99e3be8efac98734a5ddce88c1/anthropic-0.49.0-py3-none-any.whl", hash = "sha256:bbc17ad4e7094988d2fa86b87753ded8dce12498f4b85fe5810f208f454a8375", size = 243368 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
||||
{ name = "idna" },
|
||||
{ name = "sniffio" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.1.31"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diskcache"
|
||||
version = "5.6.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3f/21/1c1ffc1a039ddcc459db43cc108658f32c57d271d7289a2794e401d0fdb6/diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc", size = 67916 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/27/4570e78fc0bf5ea0ca45eb1de3818a23787af9b390c0b0a0033a1b8236f9/diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19", size = 45550 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "distro"
|
||||
version = "1.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphiti-core"
|
||||
version = "0.8.1"
|
||||
source = { directory = "../" }
|
||||
dependencies = [
|
||||
{ name = "anthropic" },
|
||||
{ name = "diskcache" },
|
||||
{ name = "mcp" },
|
||||
{ name = "neo4j" },
|
||||
{ name = "numpy" },
|
||||
{ name = "openai" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "tenacity" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "anthropic", specifier = ">=0.49.0,<0.50.0" },
|
||||
{ name = "diskcache", specifier = ">=5.6.3,<6.0.0" },
|
||||
{ name = "mcp", specifier = ">=1.5.0,<2.0.0" },
|
||||
{ name = "neo4j", specifier = ">=5.23.0,<6.0.0" },
|
||||
{ name = "numpy", specifier = ">=1.0.0" },
|
||||
{ name = "openai", specifier = ">=1.53.0,<2.0.0" },
|
||||
{ name = "pydantic", specifier = ">=2.8.2,<3.0.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.0.1,<2.0.0" },
|
||||
{ name = "tenacity", specifier = "==9.0.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx-sse"
|
||||
version = "0.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiter"
|
||||
version = "0.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/c2/e4562507f52f0af7036da125bb699602ead37a2332af0788f8e0a3417f36/jiter-0.9.0.tar.gz", hash = "sha256:aadba0964deb424daa24492abc3d229c60c4a31bfee205aedbf1acc7639d7893", size = 162604 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/82/39f7c9e67b3b0121f02a0b90d433626caa95a565c3d2449fea6bcfa3f5f5/jiter-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:816ec9b60fdfd1fec87da1d7ed46c66c44ffec37ab2ef7de5b147b2fce3fd5ad", size = 314540 },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/07/7bf6022c5a152fca767cf5c086bb41f7c28f70cf33ad259d023b53c0b858/jiter-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b1d3086f8a3ee0194ecf2008cf81286a5c3e540d977fa038ff23576c023c0ea", size = 321065 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/b2/de3f3446ecba7c48f317568e111cc112613da36c7b29a6de45a1df365556/jiter-0.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1339f839b91ae30b37c409bf16ccd3dc453e8b8c3ed4bd1d6a567193651a4a51", size = 341664 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/cf/6485a4012af5d407689c91296105fcdb080a3538e0658d2abf679619c72f/jiter-0.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ffba79584b3b670fefae66ceb3a28822365d25b7bf811e030609a3d5b876f538", size = 364635 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/f7/4a491c568f005553240b486f8e05c82547340572d5018ef79414b4449327/jiter-0.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cfc7d0a8e899089d11f065e289cb5b2daf3d82fbe028f49b20d7b809193958d", size = 406288 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/ca/f4263ecbce7f5e6bded8f52a9f1a66540b270c300b5c9f5353d163f9ac61/jiter-0.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e00a1a2bbfaaf237e13c3d1592356eab3e9015d7efd59359ac8b51eb56390a12", size = 397499 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/a2/522039e522a10bac2f2194f50e183a49a360d5f63ebf46f6d890ef8aa3f9/jiter-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1d9870561eb26b11448854dce0ff27a9a27cb616b632468cafc938de25e9e51", size = 352926 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/67/306a5c5abc82f2e32bd47333a1c9799499c1c3a415f8dde19dbf876f00cb/jiter-0.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9872aeff3f21e437651df378cb75aeb7043e5297261222b6441a620218b58708", size = 384506 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/89/c12fe7b65a4fb74f6c0d7b5119576f1f16c79fc2953641f31b288fad8a04/jiter-0.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1fd19112d1049bdd47f17bfbb44a2c0001061312dcf0e72765bfa8abd4aa30e5", size = 520621 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/2b/d57900c5c06e6273fbaa76a19efa74dbc6e70c7427ab421bf0095dfe5d4a/jiter-0.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ef5da104664e526836070e4a23b5f68dec1cc673b60bf1edb1bfbe8a55d0678", size = 512613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/05/d8b90bfb21e58097d5a4e0224f2940568366f68488a079ae77d4b2653500/jiter-0.9.0-cp310-cp310-win32.whl", hash = "sha256:cb12e6d65ebbefe5518de819f3eda53b73187b7089040b2d17f5b39001ff31c4", size = 206613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/1d/5767f23f88e4f885090d74bbd2755518050a63040c0f59aa059947035711/jiter-0.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:c43ca669493626d8672be3b645dbb406ef25af3f4b6384cfd306da7eb2e70322", size = 208371 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/44/e241a043f114299254e44d7e777ead311da400517f179665e59611ab0ee4/jiter-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6c4d99c71508912a7e556d631768dcdef43648a93660670986916b297f1c54af", size = 314654 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/1b/a7e5e42db9fa262baaa9489d8d14ca93f8663e7f164ed5e9acc9f467fc00/jiter-0.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f60fb8ce7df529812bf6c625635a19d27f30806885139e367af93f6e734ef58", size = 320909 },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/bf/8ebdfce77bc04b81abf2ea316e9c03b4a866a7d739cf355eae4d6fd9f6fe/jiter-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51c4e1a4f8ea84d98b7b98912aa4290ac3d1eabfde8e3c34541fae30e9d1f08b", size = 341733 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/4e/754ebce77cff9ab34d1d0fa0fe98f5d42590fd33622509a3ba6ec37ff466/jiter-0.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f4c677c424dc76684fea3e7285a7a2a7493424bea89ac441045e6a1fb1d7b3b", size = 365097 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/2c/6019587e6f5844c612ae18ca892f4cd7b3d8bbf49461ed29e384a0f13d98/jiter-0.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2221176dfec87f3470b21e6abca056e6b04ce9bff72315cb0b243ca9e835a4b5", size = 406603 },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/e9/c9e6546c817ab75a1a7dab6dcc698e62e375e1017113e8e983fccbd56115/jiter-0.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c7adb66f899ffa25e3c92bfcb593391ee1947dbdd6a9a970e0d7e713237d572", size = 396625 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/bd/976b458add04271ebb5a255e992bd008546ea04bb4dcadc042a16279b4b4/jiter-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c98d27330fdfb77913c1097a7aab07f38ff2259048949f499c9901700789ac15", size = 351832 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/51/fe59e307aaebec9265dbad44d9d4381d030947e47b0f23531579b9a7c2df/jiter-0.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eda3f8cc74df66892b1d06b5d41a71670c22d95a1ca2cbab73654745ce9d0419", size = 384590 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/55/5dcd2693794d8e6f4889389ff66ef3be557a77f8aeeca8973a97a7c00557/jiter-0.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd5ab5ddc11418dce28343123644a100f487eaccf1de27a459ab36d6cca31043", size = 520690 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/d5/9f51dc90985e9eb251fbbb747ab2b13b26601f16c595a7b8baba964043bd/jiter-0.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:42f8a68a69f047b310319ef8e2f52fdb2e7976fb3313ef27df495cf77bcad965", size = 512649 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/e5/4e385945179bcf128fa10ad8dca9053d717cbe09e258110e39045c881fe5/jiter-0.9.0-cp311-cp311-win32.whl", hash = "sha256:a25519efb78a42254d59326ee417d6f5161b06f5da827d94cf521fed961b1ff2", size = 206920 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/47/5e0b94c603d8e54dd1faab439b40b832c277d3b90743e7835879ab663757/jiter-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:923b54afdd697dfd00d368b7ccad008cccfeb1efb4e621f32860c75e9f25edbd", size = 210119 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/d7/c55086103d6f29b694ec79156242304adf521577530d9031317ce5338c59/jiter-0.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7b46249cfd6c48da28f89eb0be3f52d6fdb40ab88e2c66804f546674e539ec11", size = 309203 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/01/f775dfee50beb420adfd6baf58d1c4d437de41c9b666ddf127c065e5a488/jiter-0.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:609cf3c78852f1189894383cf0b0b977665f54cb38788e3e6b941fa6d982c00e", size = 319678 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/b8/09b73a793714726893e5d46d5c534a63709261af3d24444ad07885ce87cb/jiter-0.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d726a3890a54561e55a9c5faea1f7655eda7f105bd165067575ace6e65f80bb2", size = 341816 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/6f/b8f89ec5398b2b0d344257138182cc090302854ed63ed9c9051e9c673441/jiter-0.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e89dc075c1fef8fa9be219e249f14040270dbc507df4215c324a1839522ea75", size = 364152 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/ca/978cc3183113b8e4484cc7e210a9ad3c6614396e7abd5407ea8aa1458eef/jiter-0.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04e8ffa3c353b1bc4134f96f167a2082494351e42888dfcf06e944f2729cbe1d", size = 406991 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/3a/72861883e11a36d6aa314b4922125f6ae90bdccc225cd96d24cc78a66385/jiter-0.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:203f28a72a05ae0e129b3ed1f75f56bc419d5f91dfacd057519a8bd137b00c42", size = 395824 },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/67/22728a86ef53589c3720225778f7c5fdb617080e3deaed58b04789418212/jiter-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fca1a02ad60ec30bb230f65bc01f611c8608b02d269f998bc29cca8619a919dc", size = 351318 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/b9/f39728e2e2007276806d7a6609cda7fac44ffa28ca0d02c49a4f397cc0d9/jiter-0.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:237e5cee4d5d2659aaf91bbf8ec45052cc217d9446070699441a91b386ae27dc", size = 384591 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/8f/8a708bc7fd87b8a5d861f1c118a995eccbe6d672fe10c9753e67362d0dd0/jiter-0.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:528b6b71745e7326eed73c53d4aa57e2a522242320b6f7d65b9c5af83cf49b6e", size = 520746 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/1e/65680c7488bd2365dbd2980adaf63c562d3d41d3faac192ebc7ef5b4ae25/jiter-0.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9f48e86b57bc711eb5acdfd12b6cb580a59cc9a993f6e7dcb6d8b50522dcd50d", size = 512754 },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/f3/fdc43547a9ee6e93c837685da704fb6da7dba311fc022e2766d5277dfde5/jiter-0.9.0-cp312-cp312-win32.whl", hash = "sha256:699edfde481e191d81f9cf6d2211debbfe4bd92f06410e7637dffb8dd5dfde06", size = 207075 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/9d/742b289016d155f49028fe1bfbeb935c9bf0ffeefdf77daf4a63a42bb72b/jiter-0.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:099500d07b43f61d8bd780466d429c45a7b25411b334c60ca875fa775f68ccb0", size = 207999 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/1b/4cd165c362e8f2f520fdb43245e2b414f42a255921248b4f8b9c8d871ff1/jiter-0.9.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2764891d3f3e8b18dce2cff24949153ee30c9239da7c00f032511091ba688ff7", size = 308197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/aa/7a890dfe29c84c9a82064a9fe36079c7c0309c91b70c380dc138f9bea44a/jiter-0.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:387b22fbfd7a62418d5212b4638026d01723761c75c1c8232a8b8c37c2f1003b", size = 318160 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/38/5888b43fc01102f733f085673c4f0be5a298f69808ec63de55051754e390/jiter-0.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d8da8629ccae3606c61d9184970423655fb4e33d03330bcdfe52d234d32f69", size = 341259 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/5e/bbdbb63305bcc01006de683b6228cd061458b9b7bb9b8d9bc348a58e5dc2/jiter-0.9.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1be73d8982bdc278b7b9377426a4b44ceb5c7952073dd7488e4ae96b88e1103", size = 363730 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/85/53a3edc616992fe4af6814c25f91ee3b1e22f7678e979b6ea82d3bc0667e/jiter-0.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2228eaaaa111ec54b9e89f7481bffb3972e9059301a878d085b2b449fbbde635", size = 405126 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/b3/1ee26b12b2693bd3f0b71d3188e4e5d817b12e3c630a09e099e0a89e28fa/jiter-0.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:11509bfecbc319459647d4ac3fd391d26fdf530dad00c13c4dadabf5b81f01a4", size = 393668 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/87/e084ce261950c1861773ab534d49127d1517b629478304d328493f980791/jiter-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f22238da568be8bbd8e0650e12feeb2cfea15eda4f9fc271d3b362a4fa0604d", size = 352350 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/06/7dca84b04987e9df563610aa0bc154ea176e50358af532ab40ffb87434df/jiter-0.9.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17f5d55eb856597607562257c8e36c42bc87f16bef52ef7129b7da11afc779f3", size = 384204 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/2f/82e1c6020db72f397dd070eec0c85ebc4df7c88967bc86d3ce9864148f28/jiter-0.9.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:6a99bed9fbb02f5bed416d137944419a69aa4c423e44189bc49718859ea83bc5", size = 520322 },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/fd/4f0cd3abe83ce208991ca61e7e5df915aa35b67f1c0633eb7cf2f2e88ec7/jiter-0.9.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e057adb0cd1bd39606100be0eafe742de2de88c79df632955b9ab53a086b3c8d", size = 512184 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/3c/8a56f6d547731a0b4410a2d9d16bf39c861046f91f57c98f7cab3d2aa9ce/jiter-0.9.0-cp313-cp313-win32.whl", hash = "sha256:f7e6850991f3940f62d387ccfa54d1a92bd4bb9f89690b53aea36b4364bcab53", size = 206504 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/1c/0c996fd90639acda75ed7fa698ee5fd7d80243057185dc2f63d4c1c9f6b9/jiter-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:c8ae3bf27cd1ac5e6e8b7a27487bf3ab5f82318211ec2e1346a5b058756361f7", size = 204943 },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/0f/77a63ca7aa5fed9a1b9135af57e190d905bcd3702b36aca46a01090d39ad/jiter-0.9.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f0b2827fb88dda2cbecbbc3e596ef08d69bda06c6f57930aec8e79505dc17001", size = 317281 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/39/a3a1571712c2bf6ec4c657f0d66da114a63a2e32b7e4eb8e0b83295ee034/jiter-0.9.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:062b756ceb1d40b0b28f326cba26cfd575a4918415b036464a52f08632731e5a", size = 350273 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/47/3729f00f35a696e68da15d64eb9283c330e776f3b5789bac7f2c0c4df209/jiter-0.9.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6f7838bc467ab7e8ef9f387bd6de195c43bad82a569c1699cb822f6609dd4cdf", size = 206867 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mcp"
|
||||
version = "1.5.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "httpx" },
|
||||
{ name = "httpx-sse" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pydantic-settings" },
|
||||
{ name = "sse-starlette" },
|
||||
{ name = "starlette" },
|
||||
{ name = "uvicorn" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/c9/c55764824e893fdebe777ac7223200986a275c3191dba9169f8eb6d7c978/mcp-1.5.0.tar.gz", hash = "sha256:5b2766c05e68e01a2034875e250139839498c61792163a7b221fc170c12f5aa9", size = 159128 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/d1/3ff566ecf322077d861f1a68a1ff025cad337417bd66ad22a7c6f7dfcfaf/mcp-1.5.0-py3-none-any.whl", hash = "sha256:51c3f35ce93cb702f7513c12406bbea9665ef75a08db909200b07da9db641527", size = 73734 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mcp-server"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "graphiti-core" },
|
||||
{ name = "mcp" },
|
||||
{ name = "openai" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "graphiti-core", directory = "../" },
|
||||
{ name = "mcp", specifier = ">=1.5.0" },
|
||||
{ name = "openai", specifier = ">=1.68.2" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "neo4j"
|
||||
version = "5.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pytz" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/20/733dac16f7cedc80b23093415822c9763302519cba0e7c8bcdb5c01fc512/neo4j-5.28.1.tar.gz", hash = "sha256:ae8e37a1d895099062c75bc359b2cce62099baac7be768d0eba7180c1298e214", size = 231094 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/57/94225fe5e9dabdc0ff60c88cbfcedf11277f4b34e7ab1373d3e62dbdd207/neo4j-5.28.1-py3-none-any.whl", hash = "sha256:6755ef9e5f4e14b403aef1138fb6315b120631a0075c138b5ddb2a06b87b09fd", size = 312258 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.2.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e1/78/31103410a57bc2c2b93a3597340a8119588571f6a4539067546cb9a0bfac/numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f", size = 20270701 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/04/89/a79e86e5c1433926ed7d60cb267fb64aa578b6101ab645800fd43b4801de/numpy-2.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9", size = 21250661 },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/c2/f50921beb8afd60ed9589ad880332cfefdb805422210d327fb48f12b7a81/numpy-2.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae", size = 14389926 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/b9/2c4e96130b0b0f97b0ef4a06d6dae3b39d058b21a5e2fa2decd7fd6b1c8f/numpy-2.2.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775", size = 5428329 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/a5/3d7094aa898f4fc5c84cdfb26beeae780352d43f5d8bdec966c4393d644c/numpy-2.2.4-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9", size = 6963559 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/22/fb1be710a14434c09080dd4a0acc08939f612ec02efcb04b9e210474782d/numpy-2.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2", size = 14368066 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/07/2e5cc71193e3ef3a219ffcf6ca4858e46ea2be09c026ddd480d596b32867/numpy-2.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020", size = 16417040 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/97/3b1537776ad9a6d1a41813818343745e8dd928a2916d4c9edcd9a8af1dac/numpy-2.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3", size = 15879862 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/b7/4472f603dd45ef36ff3d8e84e84fe02d9467c78f92cc121633dce6da307b/numpy-2.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017", size = 18206032 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/bd/6a092963fb82e6c5aa0d0440635827bbb2910da229545473bbb58c537ed3/numpy-2.2.4-cp310-cp310-win32.whl", hash = "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a", size = 6608517 },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/e3/cb04627bc2a1638948bc13e818df26495aa18e20d5be1ed95ab2b10b6847/numpy-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542", size = 12943498 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/fb/09e778ee3a8ea0d4dc8329cca0a9c9e65fed847d08e37eba74cb7ed4b252/numpy-2.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4", size = 21254989 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/0a/1212befdbecab5d80eca3cde47d304cad986ad4eec7d85a42e0b6d2cc2ef/numpy-2.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4", size = 14425910 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/3e/e7247c1d4f15086bb106c8d43c925b0b2ea20270224f5186fa48d4fb5cbd/numpy-2.2.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f", size = 5426490 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/fa/aa7cd6be51419b894c5787a8a93c3302a1ed4f82d35beb0613ec15bdd0e2/numpy-2.2.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880", size = 6967754 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/ee/96457c943265de9fadeb3d2ffdbab003f7fba13d971084a9876affcda095/numpy-2.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1", size = 14373079 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/5c/ceefca458559f0ccc7a982319f37ed07b0d7b526964ae6cc61f8ad1b6119/numpy-2.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5", size = 16428819 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/31/9b2ac8eee99e001eb6add9fa27514ef5e9faf176169057a12860af52704c/numpy-2.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687", size = 15881470 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/dc/8569b5f25ff30484b555ad8a3f537e0225d091abec386c9420cf5f7a2976/numpy-2.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6", size = 18218144 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/05/463c023a39bdeb9bb43a99e7dee2c664cb68d5bb87d14f92482b9f6011cc/numpy-2.2.4-cp311-cp311-win32.whl", hash = "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09", size = 6606368 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/72/10c1d2d82101c468a28adc35de6c77b308f288cfd0b88e1070f15b98e00c/numpy-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91", size = 12947526 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/30/182db21d4f2a95904cec1a6f779479ea1ac07c0647f064dea454ec650c42/numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4", size = 20947156 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/6d/9483566acfbda6c62c6bc74b6e981c777229d2af93c8eb2469b26ac1b7bc/numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854", size = 14133092 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/f6/dba8a258acbf9d2bed2525cdcbb9493ef9bae5199d7a9cb92ee7e9b2aea6/numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24", size = 5163515 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/30/82116199d1c249446723c68f2c9da40d7f062551036f50b8c4caa42ae252/numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee", size = 6696558 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/b2/54122b3c6df5df3e87582b2e9430f1bdb63af4023c739ba300164c9ae503/numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba", size = 14084742 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/e2/e2cbb8d634151aab9528ef7b8bab52ee4ab10e076509285602c2a3a686e0/numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592", size = 16134051 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/21/efd47800e4affc993e8be50c1b768de038363dd88865920439ef7b422c60/numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb", size = 15578972 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/1e/f8bb88f6157045dd5d9b27ccf433d016981032690969aa5c19e332b138c0/numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f", size = 17898106 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/93/df59a5a3897c1f036ae8ff845e45f4081bb06943039ae28a3c1c7c780f22/numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00", size = 6311190 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/69/8c4f928741c2a8efa255fdc7e9097527c6dc4e4df147e3cadc5d9357ce85/numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146", size = 12644305 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/d0/bd5ad792e78017f5decfb2ecc947422a3669a34f775679a76317af671ffc/numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7", size = 20933623 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/bc/2b3545766337b95409868f8e62053135bdc7fa2ce630aba983a2aa60b559/numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0", size = 14148681 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/70/67b24d68a56551d43a6ec9fe8c5f91b526d4c1a46a6387b956bf2d64744e/numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392", size = 5148759 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/8b/e2fc8a75fcb7be12d90b31477c9356c0cbb44abce7ffb36be39a0017afad/numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc", size = 6683092 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/73/41b7b27f169ecf368b52533edb72e56a133f9e86256e809e169362553b49/numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298", size = 14081422 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/04/e208ff3ae3ddfbafc05910f89546382f15a3f10186b1f56bd99f159689c2/numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7", size = 16132202 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/bc/2218160574d862d5e55f803d88ddcad88beff94791f9c5f86d67bd8fbf1c/numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6", size = 15573131 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/78/97c775bc4f05abc8a8426436b7cb1be806a02a2994b195945600855e3a25/numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd", size = 17894270 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/eb/38c06217a5f6de27dcb41524ca95a44e395e6a1decdc0c99fec0832ce6ae/numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c", size = 6308141 },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/17/d0dd10ab6d125c6d11ffb6dfa3423c3571befab8358d4f85cd4471964fcd/numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3", size = 12636885 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/e2/793288ede17a0fdc921172916efb40f3cbc2aa97e76c5c84aba6dc7e8747/numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8", size = 20961829 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/75/bb4573f6c462afd1ea5cbedcc362fe3e9bdbcc57aefd37c681be1155fbaa/numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39", size = 14161419 },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/68/07b4cd01090ca46c7a336958b413cdbe75002286295f2addea767b7f16c9/numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd", size = 5196414 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/fd/d4a29478d622fedff5c4b4b4cedfc37a00691079623c0575978d2446db9e/numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0", size = 6709379 },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/78/96dddb75bb9be730b87c72f30ffdd62611aba234e4e460576a068c98eff6/numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960", size = 14051725 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/06/5306b8199bffac2a29d9119c11f457f6c7d41115a335b78d3f86fad4dbe8/numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8", size = 16101638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/03/74c5b631ee1ded596945c12027649e6344614144369fd3ec1aaced782882/numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc", size = 15571717 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/dc/4fc7c0283abe0981e3b89f9b332a134e237dd476b0c018e1e21083310c31/numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff", size = 17879998 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/2b/878576190c5cfa29ed896b518cc516aecc7c98a919e20706c12480465f43/numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286", size = 6366896 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/05/eb7eec66b95cf697f08c754ef26c3549d03ebd682819f794cb039574a0a6/numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d", size = 12739119 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/5c/f09c33a511aff41a098e6ef3498465d95f6360621034a3d95f47edbc9119/numpy-2.2.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8", size = 21081956 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/30/74c48b3b6494c4b820b7fa1781d441e94d87a08daa5b35d222f06ba41a6f/numpy-2.2.4-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c", size = 6827143 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/f5/ab0d2f48b490535c7a80e05da4a98902b632369efc04f0e47bb31ca97d8f/numpy-2.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d", size = 16233350 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/3a/2f6d8c1f8e45d496bca6baaec93208035faeb40d5735c25afac092ec9a12/numpy-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d", size = 12857565 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.68.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "distro" },
|
||||
{ name = "httpx" },
|
||||
{ name = "jiter" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "sniffio" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3f/6b/6b002d5d38794645437ae3ddb42083059d556558493408d39a0fcea608bc/openai-1.68.2.tar.gz", hash = "sha256:b720f0a95a1dbe1429c0d9bb62096a0d98057bcda82516f6e8af10284bdd5b19", size = 413429 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/34/cebce15f64eb4a3d609a83ac3568d43005cc9a1cba9d7fde5590fd415423/openai-1.68.2-py3-none-any.whl", hash = "sha256:24484cb5c9a33b58576fdc5acf0e5f92603024a4e39d0b99793dfa1eb14c2b36", size = 606073 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.10.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "annotated-types" },
|
||||
{ name = "pydantic-core" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.27.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-settings"
|
||||
version = "2.8.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "python-dotenv" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2025.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sse-starlette"
|
||||
version = "2.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "starlette" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419", size = 17376 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99", size = 10120 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.46.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tenacity"
|
||||
version = "9.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
version = "4.67.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.12.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.34.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "h11" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 },
|
||||
]
|
||||
2006
poetry.lock
generated
2006
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -21,18 +21,12 @@ openai = "^1.53.0"
|
|||
tenacity = "9.0.0"
|
||||
numpy = ">=1.0.0"
|
||||
python-dotenv = "^1.0.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^8.3.3"
|
||||
pytest-asyncio = "^0.24.0"
|
||||
pytest-xdist = "^3.6.1"
|
||||
ruff = "^0.7.1"
|
||||
anthropic = "~0.49.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pydantic = "^2.8.2"
|
||||
mypy = "^1.11.1"
|
||||
groq = ">=0.9,<0.12"
|
||||
anthropic = ">=0.34.1,<0.36.0"
|
||||
anthropic = "~0.49.0"
|
||||
ipykernel = "^6.29.5"
|
||||
jupyterlab = "^4.2.4"
|
||||
diskcache-stubs = "^5.6.3.6.20240818"
|
||||
|
|
@ -43,6 +37,10 @@ langchain-openai = "^0.2.6"
|
|||
sentence-transformers = "^3.2.1"
|
||||
transformers = "^4.45.2"
|
||||
voyageai = "^0.2.3"
|
||||
pytest = "^8.3.3"
|
||||
pytest-asyncio = "^0.24.0"
|
||||
pytest-xdist = "^3.6.1"
|
||||
ruff = "^0.7.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue