Skip to content

Declare identity properties, and require descriptions - #347

Merged
paul-paliychuk merged 1 commit into
v4from
paul/ontology-identity
Aug 25, 2026
Merged

Declare identity properties, and require descriptions#347
paul-paliychuk merged 1 commit into
v4from
paul/ontology-identity

Conversation

@paul-paliychuk

Copy link
Copy Markdown
Contributor

What

Two gaps in the ontology DSL, found while writing the Go and TypeScript equivalents (getzep/zep-go#111, getzep/zep-js#221). All three now behave the same way.

Identity properties

EntityType carries identity_properties, which deduplication compares when two nodes of the same type are candidates for merging. The DSL had no way to say a property is one, so an ontology declared through it could not use the feature at all.

from typing_extensions import Annotated
from zep_cloud.ontology import EntityModel, EntityText, Identity, build_ontology

class Traveler(EntityModel):
    """Someone who takes trips."""

    home_city: Annotated[EntityText, Identity] = Field(
        default=None, description="The city they live in"
    )

Listed in declaration order. Edge types have none, since only nodes are deduplicated.

Descriptions are now required

A missing description raises ValueError naming the type and property, rather than sending an empty string.

Both a type description (the docstring) and a property description go into the extraction prompt as the account of what belongs to the type. An empty one is accepted by the API, so an undescribed property was a silent quality loss rather than a failure — the shape of bug the DSL's existing "is not an ontology property" error already exists to prevent.

This is a break for a declaration that left a description out:

# before: accepted, sent description=""
home_city: EntityText = None

# now
home_city: EntityText = Field(default=None, description="The city they live in")

Worth taking inside the alpha: the error names the type and property, so the fix is mechanical, and the Go and TypeScript DSLs reject the same thing.

One other change to match: the name in each message is the ontology type name the caller wrote — the dict key, which is what the API sees — rather than the Python class name.

Tests

14, up from 8. New: the identity annotation, declaration order, a type with none, an edge property never becoming one, and one per rejection — a property with no description, an entity with no docstring, an edge with no docstring.

🤖 Generated with Claude Code

EntityType carries identity_properties, which is what deduplication compares
when two nodes of the same type are candidates for merging. The DSL had no way
to say a property is one, so an ontology declared through it could not use the
feature at all. A property annotated Annotated[EntityText, Identity] is now
listed in the type's identity_properties, in declaration order. Edge types have
no identity properties, since only nodes are deduplicated.

A missing description is now an error rather than an empty string. Both a type
description and a property description go into the extraction prompt as the
account of what belongs to the type, and the ontology write path does not
reject an empty one, so an undescribed property degraded extraction silently.
This is a break for a declaration that left one out, which is worth taking
inside the alpha: the Go and TypeScript DSLs reject the same thing, and the
error names the type and property so the fix is mechanical.

The name in each message is the ontology type name the caller wrote, which is
what the API sees, rather than the Python class name.
@paul-paliychuk
paul-paliychuk merged commit b41aae8 into v4 Aug 25, 2026
4 checks passed
@paul-paliychuk
paul-paliychuk deleted the paul/ontology-identity branch August 25, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant