PydanticAI, observation scopes, and entity labels
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")
Observation scopes
Control consolidation granularity with observation_scopes on retain items. Example tags: student:alice, teacher:bob, session-id:s1.
| Scope | Behavior |
|---|---|
per_tag | One pass per individual tag |
combined (default) | One pass with all tags together |
all_combinations | Every non-empty tag subset |
custom | Explicit 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.
| Type | Behavior |
|---|---|
value | Single enum value |
multi-values | Multiple enum values |
text | Free-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
nullforincludeEntities: false