Skip to content

agent-memory-ability

Domain layer for conversational agent memory in the KĀDI framework. A thin, opinionated wrapper over graph-ability providing 7 memory-* tools with enforced Memory schema defaults, automatic agent isolation, conversation tracking, cascade deletion, and LLM summarization.

  • 7 memory-specific tools — store, recall, context, relate, forget, conversations, summarize
  • Agent isolation — every query is automatically scoped to the calling agent
  • Conversation sessions — group memories by conversationId, track duration and count
  • LLM summarization — generate conversation summaries via chat-completion
  • Cascade delete — forget a memory and automatically clean up orphaned Topics/Entities
  • Three deployment modes — native library, remote broker ability, or standalone CLI
  • Vault-first credentials — API keys loaded from the models vault via secret-ability; no .env files
  • Comprehensive test suite — 58 unit tests + 19 integration tests
Terminal window
kadi install agent-memory-ability
import { KadiClient } from '@kadi.build/core';
const client = new KadiClient({ name: 'my-agent', version: '1.0.0' });
const memory = await client.loadNative('agent-memory-ability');
// Store a memory
const stored = await memory.invoke('memory-store', {
content: 'The user prefers dark mode and uses TypeScript.',
agent: 'assistant-v1',
conversationId: 'session-42',
importance: 0.8,
});
console.log(stored.rid); // e.g. "#12:0"
// Recall memories (hybrid search: semantic + keyword + graph)
const results = await memory.invoke('memory-recall', {
query: 'what are the user preferences?',
agent: 'assistant-v1',
});
console.log(results.results);
// Get conversation context via graph traversal
const context = await memory.invoke('memory-context', {
query: 'user preferences',
agent: 'assistant-v1',
depth: 2,
});
// Relate two memories
await memory.invoke('memory-relate', {
fromRid: '#12:0',
toRid: '#12:5',
relationship: 'contradicts',
weight: 0.9,
});
// List conversations
const convos = await memory.invoke('memory-conversations', {
agent: 'assistant-v1',
limit: 10,
});
// Summarize a conversation
const summary = await memory.invoke('memory-summarize', {
conversationId: 'session-42',
});
// Forget with cascade cleanup
await memory.invoke('memory-forget', {
rid: '#12:0',
confirm: true,
cascade: true,
});
const client = new KadiClient({
name: 'my-agent',
version: '1.0.0',
brokers: { default: { url: 'wss://broker.kadi.build/kadi' } },
});
await client.connect();
// agent-memory-ability must be running on the same broker
const result = await client.invokeRemote('memory-store', {
content: 'Remember this from the broker!',
agent: 'assistant-v1',
});
Terminal window
# Broker mode — connect to broker and serve tools
kadi run start
# Or directly
node dist/index.js broker
# STDIO mode
node dist/index.js stdio

Store a memory with automatic entity extraction, embedding, and graph linking. Enforces vertexType=Memory, auto-adds agent and timestamp, creates Conversation vertex and InConversation edge when conversationId is provided.

ParameterTypeRequiredDescription
contentstringyesMemory content to store
agentstringnoAgent identifier (default: from config)
topicsstring[]noExplicit topics (skips extraction)
entities{name, type}[]noExplicit entities (skips extraction)
conversationIdstringnoConversation session ID
importancenumbernoImportance score 0–1
metadataRecord<string, unknown>noArbitrary metadata (JSON-stringified)
skipExtractionbooleannoSkip LLM extraction entirely

Returns: { stored, rid, agent, conversationId?, topics, entities, importance, embeddingDimensions, durationMs }

Pipeline: validate → build graph-store params → delegate to graph-store → upsert Conversation → create InConversation edge.


Search stored memories with automatic agent isolation. Default mode is hybrid (semantic + keyword + graph with RRF fusion and importance weighting).

ParameterTypeRequiredDescription
querystringyesSearch query
agentstringnoAgent identifier (default: from config)
limitnumbernoMax results (default: 10)
mode'semantic' | 'keyword' | 'graph' | 'hybrid'noSearch mode (default: hybrid)
signalsstring[]noSignals for hybrid (default: ['semantic','keyword','graph'])
topicsstring[]noTopic filter for graph signal
conversationIdstringnoFilter to a specific conversation

Returns: { results: SignalResult[], count, agent, mode, signals }

Note: The structural signal is intentionally excluded from defaults — memories use topic/entity edges, not direct structural links.


Retrieve rich graph context around a topic, entity, or memory. Supports four modes:

  • Query mode — recall + graph expansion (delegates to graph-context)
  • RID mode — start from a specific memory RID
  • Topic mode — traverse from a named Topic vertex
  • Entity mode — traverse from a named Entity vertex
ParameterTypeRequiredDescription
querystringnoSearch query for recall-based context
topicstringnoTopic name to start from
entitystringnoEntity name to start from
entityTypestringnoEntity type filter
memoryRidstringnoMemory RID to start from
agentstringnoAgent filter
depthnumbernoTraversal depth 1–4 (default: 2)
limitnumbernoMax results to expand (default: 5)

Returns (query): { results: [...{ neighbors, edges }], count, depth, agent } Returns (RID/topic/entity): { found, startRid, depth, vertices, edges, vertexCount, edgeCount, agent }


Create a typed, weighted RelatedTo edge between any two vertices.

ParameterTypeRequiredDescription
fromRidstringyesSource vertex RID
toRidstringyesTarget vertex RID
relationshipstringnoRelationship type (default: "related")
weightnumbernoEdge weight 0–1 (default: 0.5)
bidirectionalbooleannoCreate reverse edge too (default: false)

Returns: { created, from, to, relationship, weight, bidirectional }


Delete memories with a safety guard. Requires confirm: true. Supports single-RID deletion, bulk deletion by agent/conversation/date, and optional cascade cleanup of orphaned Topics and Entities.

ParameterTypeRequiredDescription
ridstringnoSpecific Memory RID to delete
agentstringnoDelete all memories for this agent
conversationIdstringnoDelete memories in this conversation
olderThanstringnoDelete memories older than this ISO date
confirmbooleanyesMust be true to proceed
cascadebooleannoRemove orphaned Topics/Entities (default: false)

Returns: { deleted, memoriesRemoved, orphansRemoved }

At least one filter (rid, agent, conversationId, or olderThan) is required.


List conversation sessions sorted by most recent.

ParameterTypeRequiredDescription
agentstringnoAgent identifier (default: from config)
sincestringnoOnly conversations after this ISO date
limitnumbernoMax results (default: 20, clamped 1–100)

Returns: { conversations: [...{ conversationId, startTime, endTime, duration?, memoryCount, summary? }], count, agent }


Generate a 2–4 sentence summary of all memories in a conversation via LLM. Stores the summary on the Conversation vertex for future retrieval.

ParameterTypeRequiredDescription
conversationIdstringyesConversation ID to summarize

Returns: { summarized, conversationId, memoryCount, summary }

┌─────────────────────────┐
│ agent-memory-ability │
│ 7 memory-* tools │
│ Schema enforcement │
│ Agent isolation │
│ Conversation tracking │
└────────────┬────────────┘
│ graphAbility.invoke()
┌────────────▼────────────┐
│ graph-ability │
│ 15 graph-* tools │
│ N-signal hybrid search │
│ Schema registry │
│ Batch pipeline │
│ SQL/chat passthrough │
└────────────┬────────────┘
│ invokeRemote (graph-ability's
│ own broker connection)
┌────────────▼────────────┐ ┌──────────────────┐
│ arcadedb-ability │ │ model-manager │
│ ArcadeDB SQL bridge │ │ create-embedding │
│ │ │ chat-completion │
└──────────────────────────┘ └──────────────────┘

Key design: agent-memory-ability never connects to a broker itself. All 7 tools route through graphAbility.invoke() (the loaded native instance of graph-ability), which in turn calls arcadedb-ability and model-manager via its own broker connection. This means agent-memory-ability has zero direct broker traffic when loaded natively.

ModeHow it worksUse case
Nativeclient.loadNative('agent-memory-ability') imports the module in-process. Top-level await ensures vault credentials and all tools are ready before the import resolves. All calls route through graph-ability’s native instance — no broker connection opened.Agents that want zero-latency memory access
Remoteclient.invokeRemote('memory-store', ...) routes through the KĀDI broker to a running instance.Distributed agents on the same broker
CLIkadi run start connects to broker and serves all 7 tools.Standalone deployment (Docker, Akash)

agent-memory-ability registers the agent-memory schema on startup:

Memory — individual agent memories

PropertyTypeIndex
contentSTRINGFULL_TEXT
agentSTRINGNOTUNIQUE
timestampDATETIMENOTUNIQUE
importanceDOUBLE
embeddingEMBEDDEDLIST
conversationIdSTRING
metadataSTRING

Conversation — conversation sessions

PropertyTypeIndex
conversationIdSTRINGUNIQUE
agentSTRINGNOTUNIQUE
startTimeDATETIME
endTimeDATETIME
summarySTRING
memoryCountINTEGER

Topic / Entity — inherited from graph-ability (see graph-ability README)

EdgePropertiesPurpose
HasTopicweightMemory → Topic
MentionscontextMemory → Entity
RelatedTotype, weight, createdAtAny → Any
InConversationMemory → Conversation
REMEMBERED_DURINGtimestampMemory → Conversation

Settings are resolved in order (highest priority wins):

  1. Environment variablesMEMORY_DATABASE, MEMORY_API_KEY, etc.
  2. Vault "models"MEMORY_API_KEY, MEMORY_API_URL via secret-ability
  3. config.yml — walk-up discovery from CWD (memory: section)
  4. Built-in defaults

Example config — see config.sample.yml in this repo for a fully-commented reference. Copy or merge the memory: section into your project’s config.yml.

FieldEnv Varconfig.ymlDefault
databaseMEMORY_DATABASEmemory.databasekadi_memory
embeddingModelMEMORY_EMBEDDING_MODELmemory.embedding_modeltext-embedding-3-small
extractionModelMEMORY_EXTRACTION_MODELmemory.extraction_modelgpt-5-nano
summarizationModelMEMORY_SUMMARIZATION_MODELmemory.summarization_modelgpt-5-mini
chatModelMEMORY_CHAT_MODELmemory.chat_modelgpt-5-mini
defaultAgentMEMORY_DEFAULT_AGENTmemory.default_agentdefault
apiKeyMEMORY_API_KEY(vault only)
apiUrlMEMORY_API_URL(vault only)
embeddingTransportMEMORY_EMBEDDING_TRANSPORTmemory.embedding_transportapi
chatTransportMEMORY_CHAT_TRANSPORTmemory.chat_transportapi
Terminal window
kadi secret set --vault models --key MEMORY_API_KEY --value "sk-..."
kadi secret set --vault models --key MEMORY_API_URL --value "https://api.openai.com"
{
"name": "agent-memory-ability",
"version": "0.0.7",
"type": "ability",
"entrypoint": "dist/index.js",
"abilities": {
"graph-ability": "^0.0.5",
"secret-ability": "^0.9.0"
},
"brokers": {
"default": "wss://broker.kadi.build/kadi"
}
}
Terminal window
# Build the container
kadi build
# Deploy locally
kadi deploy local
# Deploy to Akash
kadi deploy akash

The container receives vault secrets at startup via kadi secret receive --vault models before running kadi run start.

ServicePurposeRequired
KĀDI BrokerTool routingyes
arcadedb-abilityArcadeDB SQL bridge (arcade-command, arcade-query)yes
model-managerEmbeddings + LLM (create-embedding, chat-completion)yes
ArcadeDBGraph databaseyes
secret-abilityVault credential managementyes (for vault mode)
graph-abilityLoaded natively or available on brokeryes
Terminal window
# Run all tests
npm test
# Unit tests only (no infra required)
npm run test:unit
# Integration tests (requires full infra)
npm run test:integration
SuiteTestsDescription
store-wrapper.test.ts15Schema enforcement, auto-agent, auto-timestamp, conversation edges, metadata, embedding config
recall-wrapper.test.ts16Schema enforcement, agent isolation, 3-signal default, custom signals, mode, limit, filters
forget-cascade.test.ts13Safety guard, filter validation, single/bulk delete, cascade orphan cleanup
conversations.test.ts14Agent filter, date filter, limit clamping, duration calculation, query patterns
Unit total58
lifecycle.test.ts5Store → recall → context → summarize → forget (full pipeline)
full-lifecycle.test.ts8Store×2 → recall → relate → verify → forget×2 → confirm deletion
agent-isolation.test.ts6Agent-A/B storage and retrieval isolation
Integration total19

Tests load graph-ability in-process (native) and patch invokeRemote for local tool routing:

memory-* tools (test client)
→ graph-* tools (graph-ability, in-process)
→ arcade-command / arcade-query (broker)
→ create-embedding / chat-completion (broker)

This avoids needing graph-ability on the broker during tests while still exercising the full tool chain.

Terminal window
# Install dependencies
npm install
# Install KĀDI abilities (graph-ability, secret-ability)
kadi install
# Build
npm run build
# Dev mode (tsx, no compile step)
npm run dev
agent-memory-ability/
├── agent.json # KĀDI ability manifest
├── config.sample.yml # Example config.yml (copy/merge into your project)
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── src/
│ ├── index.ts # Entry point — top-level await init + exports
│ ├── lib/
│ │ └── config.ts # Config resolution (env → vault → yml → defaults)
│ └── tools/
│ ├── store.ts # memory-store
│ ├── recall.ts # memory-recall
│ ├── context.ts # memory-context
│ ├── relate.ts # memory-relate
│ ├── forget.ts # memory-forget
│ ├── conversations.ts # memory-conversations
│ └── summarize.ts # memory-summarize
├── tests/
│ ├── unit/
│ │ ├── store-wrapper.test.ts
│ │ ├── recall-wrapper.test.ts
│ │ ├── forget-cascade.test.ts
│ │ └── conversations.test.ts
│ └── integration/
│ ├── helpers.ts # Test context, invokeRemote patching, cleanup
│ ├── lifecycle.test.ts
│ ├── full-lifecycle.test.ts
│ └── agent-isolation.test.ts
└── abilities/ # Installed KĀDI abilities (kadi install)
├── graph-ability@0.0.5/
└── secret-ability@0.9.1/

When used as a native library:

ExportTypeDescription
defaultKadiClientPre-configured client with all 7 tools registered
MEMORY_SCHEMASchemaDefinitionFull graph schema definition
MEMORY_VERTEXVertexTypeDefMemory vertex type definition
CONVERSATION_VERTEXVertexTypeDefConversation vertex type definition
loadMemoryConfig()() => MemoryConfigSync config (no vault)
loadMemoryConfigWithVault(client)(client) => Promise<MemoryConfig>Async config with vault
MemoryConfigtypeConfiguration interface

Proprietary — HuMIn Game Lab