graphiti icon indicating copy to clipboard operation
graphiti copied to clipboard

Add support for datetime fields in custom entities

Open guilherme-takata opened this issue 6 months ago • 6 comments

I defined a custom entity that has a datetime object as a field, when trying to insert a new episode using this custom entity I always get an error at:

graphiti_core/prompts/dedupe_nodes.py", line 66, in node {json.dumps(context['existing_nodes'], indent=2)}

Any way we could simply set the default argument in this line to str so we avoid raising errors whenever we get a non serializable field?

guilherme-takata avatar Jun 19 '25 03:06 guilherme-takata

Hey, this current limitation is due to the fact that LLMs will output the extracted attributes in JSON format, even when using pydantic structured output with providers like Google or OpenAI.

As such, we can't explicitly support datetimes and other non-JSON types. A workaround for this is to use a string and in the description mention that it should represent an ISO 8601 date format. If you need a Python datetime value, you can always convert the ISO 8601 strings to Python date times using the datetime library.

In terms of adding a default argument, in general we want to avoid behavior that fails silently or changes the types of user inputs silently as this could be confusing when using the package. Throwing an error here is ideal as it signals that an incompatible type is being used.

prasmussen15 avatar Jul 01 '25 16:07 prasmussen15

Thanks for the clarification, @prasmussen15. I wish I had found this 5+ hours earlier.

It might be worth updating the docs to reflect this limitation, as they currently have examples explicitly using datetime:

from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional

# Custom Entity Types
class Person(BaseModel):
    """A person entity with biographical information."""
    age: Optional[int] = Field(None, description="Age of the person")
    occupation: Optional[str] = Field(None, description="Current occupation")
    location: Optional[str] = Field(None, description="Current location")
    birth_date: Optional[datetime] = Field(None, description="Date of birth")

class Company(BaseModel):
    """A business organization."""
    industry: Optional[str] = Field(None, description="Primary industry")
    founded_year: Optional[int] = Field(None, description="Year company was founded")
    headquarters: Optional[str] = Field(None, description="Location of headquarters")
    employee_count: Optional[int] = Field(None, description="Number of employees")

class Product(BaseModel):
    """A product or service."""
    category: Optional[str] = Field(None, description="Product category")
    price: Optional[float] = Field(None, description="Price in USD")
    release_date: Optional[datetime] = Field(None, description="Product release date")

# Custom Edge Types
class Employment(BaseModel):
    """Employment relationship between a person and company."""
    position: Optional[str] = Field(None, description="Job title or position")
    start_date: Optional[datetime] = Field(None, description="Employment start date")
    end_date: Optional[datetime] = Field(None, description="Employment end date")
    salary: Optional[float] = Field(None, description="Annual salary in USD")
    is_current: Optional[bool] = Field(None, description="Whether employment is current")

class Investment(BaseModel):
    """Investment relationship between entities."""
    amount: Optional[float] = Field(None, description="Investment amount in USD")
    investment_type: Optional[str] = Field(None, description="Type of investment (equity, debt, etc.)")
    stake_percentage: Optional[float] = Field(None, description="Percentage ownership")
    investment_date: Optional[datetime] = Field(None, description="Date of investment")

class Partnership(BaseModel):
    """Partnership relationship between companies."""
    partnership_type: Optional[str] = Field(None, description="Type of partnership")
    duration: Optional[str] = Field(None, description="Expected duration")
    deal_value: Optional[float] = Field(None, description="Financial value of partnership")

0xtotaylor avatar Jul 24 '25 18:07 0xtotaylor

@guilherme-takata Is this still relevant? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 05 '25 00:10 claude[bot]

@guilherme-takata Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 22 '25 00:10 claude[bot]

@guilherme-takata Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 29 '25 00:10 claude[bot]

@guilherme-takata Is this still relevant? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Nov 17 '25 00:11 claude[bot]