Skip to main content

PydanticAI, observation scopes, and entity labels

· 2 min read

Attach Atulya to PydanticAI agents, control how observations consolidate across tags, define entity label vocabularies, and retain timeless reference content.

PydanticAI integration

from atulya_client import Atulya
from atulya_pydantic_ai import create_atulya_tools, memory_instructions
from pydantic_ai import Agent

client = Atulya(base_url="http://localhost:8888")

agent = Agent(
"openai:gpt-4o",
tools=create_atulya_tools(client=client, bank_id="user-123"),
instructions=[memory_instructions(client=client, bank_id="user-123")],
)

result = await agent.run("What do you remember about my preferences?")

Tools: atulya_retain, atulya_recall, atulya_reflect. memory_instructions preloads context each run.

Global defaults:

from atulya_pydantic_ai import configure, create_atulya_tools

configure(
atulya_api_url="http://localhost:8888",
budget="mid",
max_tokens=4096,
tags=["env:prod"],
recall_tags=["scope:global"],
recall_tags_match="any",
)

tools = create_atulya_tools(bank_id="user-123")

PydanticAI docs

Observation scopes

Control consolidation granularity with observation_scopes on retain items. Example tags: student:alice, teacher:bob, session-id:s1.

ScopeBehavior
per_tagOne pass per individual tag
combined (default)One pass with all tags together
all_combinationsEvery non-empty tag subset
customExplicit list of tag sets
[["student:alice"], ["teacher:bob"], ["teacher:bob", "session-id:s1"]]

Scopes are isolated: a memory under ["student:alice"] never bleeds into ["student:alice", "teacher:bob"].

Richer entity labels

Bank-level entity_labels define controlled key:value extraction that becomes graph-linked entities.

TypeBehavior
valueSingle enum value
multi-valuesMultiple enum values
textFree-form string

Optional fields skip extraction when content is thin. Set via bank config API.

Timestamp unset

Reference material without a real event date:

client.retain(
bank_id="my-bank",
content="Quick sort average case is O(n log n).",
timestamp="unset",
)

Extraction sees Event Date: Unknown and can return N/A for temporal fields instead of inventing dates.

Performance

Database work for large banks (tested up to ~100k memories, ~100M entity links):

  • Retain: up to ~10x faster at scale
  • Recall: up to ~20x better on graph/temporal paths at very large scale

No configuration required.

Also worth knowing

  • OpenClaw auto-retain: sliding window every N turns (retainEveryNTurns, default 10)
  • Configurable Gemini/Vertex safety settings
  • Document list API tag filtering
  • Extension hooks for routing and error headers
  • Reflect context truncation fix for context_length_exceeded
  • Consolidation deadlock fix after zombie tasks
  • Control plane observation count fix
  • Bank-scoped request validation
  • TypeScript SDK sends null for includeEntities: false

Changelog