-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
The MemoryService provides event ingestion and query operations for the agent memory system.
Proto file: proto/memory.proto
Ingest a conversation event into storage.
Request:
message IngestEventRequest {
Event event = 1;
}
message Event {
string event_id = 1; // ULID, client-generated
string session_id = 2; // Session identifier
int64 timestamp_ms = 3; // Unix epoch milliseconds
EventType event_type = 4; // Type of event
EventRole role = 5; // Author role
string text = 6; // Content
map<string, string> metadata = 7; // Optional metadata
}Response:
message IngestEventResponse {
string event_id = 1; // The stored event ID
bool created = 2; // True if new, false if duplicate (idempotent)
}Errors:
-
INVALID_ARGUMENT: Missing or empty event_id or session_id -
INVALID_ARGUMENT: Invalid timestamp (out of valid range) -
INTERNAL: Storage write failure
Example:
grpcurl -plaintext -d '{
"event": {
"event_id": "01HXYZABC123",
"session_id": "session-456",
"timestamp_ms": 1706600000000,
"event_type": 2,
"role": 1,
"text": "What is Rust?"
}
}' localhost:50051 memory.MemoryService/IngestEventGet root TOC nodes (year level).
Request:
message GetTocRootRequest {}Response:
message GetTocRootResponse {
repeated TocNode nodes = 1; // Year nodes, sorted by time descending
}Example:
grpcurl -plaintext localhost:50051 memory.MemoryService/GetTocRootGet a specific TOC node by ID.
Request:
message GetNodeRequest {
string node_id = 1; // e.g., "toc:year:2026", "toc:month:2026-01"
}Response:
message GetNodeResponse {
optional TocNode node = 1; // Null if not found
}Example:
grpcurl -plaintext -d '{"node_id": "toc:year:2026"}' \
localhost:50051 memory.MemoryService/GetNodeBrowse children of a TOC node with pagination.
Request:
message BrowseTocRequest {
string parent_id = 1; // Parent node ID
int32 limit = 2; // Max results per page
optional string continuation_token = 3; // Token from previous response
}Response:
message BrowseTocResponse {
repeated TocNode children = 1; // Child nodes
optional string continuation_token = 2; // Token for next page (null if no more)
bool has_more = 3; // True if more results available
}Example:
# First page
grpcurl -plaintext -d '{"parent_id": "toc:year:2026", "limit": 10}' \
localhost:50051 memory.MemoryService/BrowseToc
# Next page (using token from previous response)
grpcurl -plaintext -d '{
"parent_id": "toc:year:2026",
"limit": 10,
"continuation_token": "abc123..."
}' localhost:50051 memory.MemoryService/BrowseTocGet events in a time range.
Request:
message GetEventsRequest {
int64 from_timestamp_ms = 1; // Start time (inclusive)
int64 to_timestamp_ms = 2; // End time (inclusive)
int32 limit = 3; // Max events to return
}Response:
message GetEventsResponse {
repeated Event events = 1; // Events in range, sorted by time
bool has_more = 2; // True if more events beyond limit
}Example:
grpcurl -plaintext -d '{
"from_timestamp_ms": 1706600000000,
"to_timestamp_ms": 1706700000000,
"limit": 100
}' localhost:50051 memory.MemoryService/GetEventsExpand a grip to show context events around the excerpt.
Request:
message ExpandGripRequest {
string grip_id = 1; // Grip ID to expand
optional int32 events_before = 2; // Events before excerpt (default: 5)
optional int32 events_after = 3; // Events after excerpt (default: 5)
}Response:
message ExpandGripResponse {
optional Grip grip = 1; // The grip (null if not found)
repeated Event events_before = 2; // Events before excerpt
repeated Event excerpt_events = 3; // Events containing the excerpt
repeated Event events_after = 4; // Events after excerpt
}Example:
grpcurl -plaintext -d '{
"grip_id": "grip:1706600000000:01HXYZ",
"events_before": 3,
"events_after": 3
}' localhost:50051 memory.MemoryService/ExpandGripA conversation event.
message Event {
string event_id = 1;
string session_id = 2;
int64 timestamp_ms = 3;
EventType event_type = 4;
EventRole role = 5;
string text = 6;
map<string, string> metadata = 7;
}| Field | Type | Description |
|---|---|---|
event_id |
string | ULID identifier (client-generated, 26 chars) |
session_id |
string | Session identifier (any non-empty string) |
timestamp_ms |
int64 | Unix epoch milliseconds |
event_type |
EventType | Type of event (see enum below) |
role |
EventRole | Author role (see enum below) |
text |
string | Event content |
metadata |
map | Optional key-value pairs |
enum EventType {
EVENT_TYPE_UNSPECIFIED = 0;
EVENT_TYPE_SESSION_START = 1;
EVENT_TYPE_USER_MESSAGE = 2;
EVENT_TYPE_ASSISTANT_MESSAGE = 3;
EVENT_TYPE_TOOL_RESULT = 4;
EVENT_TYPE_ASSISTANT_STOP = 5;
EVENT_TYPE_SUBAGENT_START = 6;
EVENT_TYPE_SUBAGENT_STOP = 7;
EVENT_TYPE_SESSION_END = 8;
}| Value | Description |
|---|---|
SESSION_START |
Conversation session begins |
USER_MESSAGE |
User prompt/input |
ASSISTANT_MESSAGE |
AI response |
TOOL_RESULT |
Tool execution output |
ASSISTANT_STOP |
AI stops generating |
SUBAGENT_START |
Subagent spawned |
SUBAGENT_STOP |
Subagent completes |
SESSION_END |
Session ends |
enum EventRole {
EVENT_ROLE_UNSPECIFIED = 0;
EVENT_ROLE_USER = 1;
EVENT_ROLE_ASSISTANT = 2;
EVENT_ROLE_SYSTEM = 3;
EVENT_ROLE_TOOL = 4;
}| Value | Description |
|---|---|
USER |
Human user |
ASSISTANT |
AI assistant |
SYSTEM |
System message |
TOOL |
Tool output |
A node in the Table of Contents hierarchy.
message TocNode {
string node_id = 1;
TocLevel level = 2;
string title = 3;
optional string summary = 4;
repeated TocBullet bullets = 5;
repeated string keywords = 6;
repeated string child_node_ids = 7;
int64 start_time_ms = 8;
int64 end_time_ms = 9;
int32 version = 10;
}| Field | Type | Description |
|---|---|---|
node_id |
string | Unique identifier (e.g., "toc:year:2026") |
level |
TocLevel | Hierarchy level |
title |
string | Human-readable title |
summary |
string | Optional summary text |
bullets |
TocBullet[] | Summary bullet points |
keywords |
string[] | Searchable keywords |
child_node_ids |
string[] | Child node IDs |
start_time_ms |
int64 | Period start timestamp |
end_time_ms |
int64 | Period end timestamp |
version |
int32 | Version number (increases on update) |
enum TocLevel {
TOC_LEVEL_UNSPECIFIED = 0;
TOC_LEVEL_YEAR = 1;
TOC_LEVEL_MONTH = 2;
TOC_LEVEL_WEEK = 3;
TOC_LEVEL_DAY = 4;
TOC_LEVEL_SEGMENT = 5;
}A bullet point in a TOC node.
message TocBullet {
string text = 1;
repeated string grip_ids = 2;
}| Field | Type | Description |
|---|---|---|
text |
string | Bullet text |
grip_ids |
string[] | IDs of grips supporting this bullet |
Provenance anchor linking summaries to source events.
message Grip {
string grip_id = 1;
string excerpt = 2;
string event_id_start = 3;
string event_id_end = 4;
int64 timestamp_ms = 5;
string source = 6;
}| Field | Type | Description |
|---|---|---|
grip_id |
string | Unique identifier |
excerpt |
string | Text excerpt from source |
event_id_start |
string | First event in excerpt |
event_id_end |
string | Last event in excerpt |
timestamp_ms |
int64 | Timestamp of first event |
source |
string | Creator (e.g., "segment_summarizer") |
Search a specific TOC node for term matches.
Request:
message SearchNodeRequest {
string node_id = 1; // Node to search
string query = 2; // Search terms
repeated SearchField fields = 3; // Fields to search
float min_score = 4; // Minimum match score (0.0-1.0, default 0.3)
}Response:
message SearchNodeResponse {
repeated SearchMatch matches = 1; // Matching content with scores
int32 total_matches = 2; // Total number of matches
}Errors:
-
INVALID_ARGUMENT: Empty node_id or query -
NOT_FOUND: Node does not exist -
INVALID_ARGUMENT: min_score outside 0.0-1.0 range
Example:
grpcurl -plaintext -d '{
"node_id": "toc:day:2026-01-15",
"query": "rust async",
"fields": ["SEARCH_FIELD_TITLE", "SEARCH_FIELD_SUMMARY", "SEARCH_FIELD_KEYWORDS"],
"min_score": 0.5
}' localhost:50051 memory.MemoryService/SearchNodeSearch children of a TOC node recursively.
Request:
message SearchChildrenRequest {
string parent_id = 1; // Parent node
string query = 2; // Search terms
int32 max_depth = 3; // Max levels to search (default 3)
int32 limit = 4; // Max results (default 20)
float min_score = 5; // Minimum match score (default 0.3)
}Response:
message SearchChildrenResponse {
repeated NodeMatch matches = 1; // Matching nodes with scores
int32 nodes_searched = 2; // Number of nodes searched
}Errors:
-
INVALID_ARGUMENT: Empty parent_id or query -
NOT_FOUND: Parent node does not exist -
INVALID_ARGUMENT: max_depth or limit less than 1
Example:
grpcurl -plaintext -d '{
"parent_id": "toc:month:2026-01",
"query": "memory optimization",
"max_depth": 2,
"limit": 10,
"min_score": 0.4
}' localhost:50051 memory.MemoryService/SearchChildrenCheck BM25 index availability and stats.
Request:
message GetTeleportStatusRequest {}Response:
message GetTeleportStatusResponse {
bool available = 1; // True if index is ready
int64 document_count = 2; // Number of indexed documents
int64 size_bytes = 3; // Index size in bytes
int64 last_commit = 4; // Last commit timestamp (epoch ms)
}Example:
grpcurl -plaintext localhost:50051 memory.MemoryService/GetTeleportStatusBM25 keyword search across indexed documents.
Request:
message TeleportSearchRequest {
string query = 1; // Search query
int32 limit = 2; // Max results (default 20)
repeated DocType doc_types = 3; // Filter by doc type (default both)
}Response:
message TeleportSearchResponse {
repeated TeleportResult results = 1; // Matches with BM25 scores
int64 query_time_ms = 2; // Query execution time
}Errors:
-
INVALID_ARGUMENT: Empty query -
UNAVAILABLE: BM25 index not available
Example:
grpcurl -plaintext -d '{
"query": "tokio async runtime",
"limit": 10,
"doc_types": ["DOC_TYPE_TOC_NODE", "DOC_TYPE_GRIP"]
}' localhost:50051 memory.MemoryService/TeleportSearchCheck vector index availability.
Request:
message GetVectorIndexStatusRequest {}Response:
message GetVectorIndexStatusResponse {
bool available = 1; // True if index is ready
int64 vector_count = 2; // Number of indexed vectors
int32 dimension = 3; // Vector dimension (e.g., 384, 768)
int64 size_bytes = 4; // Index size in bytes
}Example:
grpcurl -plaintext localhost:50051 memory.MemoryService/GetVectorIndexStatusSemantic similarity search using embeddings.
Request:
message VectorTeleportRequest {
string query = 1; // Natural language query
int32 limit = 2; // Max results (default 20)
}Response:
message VectorTeleportResponse {
repeated VectorResult results = 1; // Matches with cosine similarity scores
int64 query_time_ms = 2; // Query execution time
}Errors:
-
INVALID_ARGUMENT: Empty query -
UNAVAILABLE: Vector index not available
Example:
grpcurl -plaintext -d '{
"query": "how to handle errors in async Rust",
"limit": 15
}' localhost:50051 memory.MemoryService/VectorTeleportCombined BM25 + vector search using Reciprocal Rank Fusion (RRF k=60).
Request:
message HybridSearchRequest {
string query = 1; // Search query
int32 limit = 2; // Max results (default 20)
float bm25_weight = 3; // BM25 contribution (default 0.5)
float vector_weight = 4; // Vector contribution (default 0.5)
}Response:
message HybridSearchResponse {
repeated HybridResult results = 1; // Fused results with combined scores
bool bm25_available = 2; // True if BM25 was used
bool vector_available = 3; // True if vector was used
}Errors:
-
INVALID_ARGUMENT: Empty query -
INVALID_ARGUMENT: Weights must be between 0.0 and 1.0 -
UNAVAILABLE: Neither index available
Example:
grpcurl -plaintext -d '{
"query": "async error handling patterns",
"limit": 20,
"bm25_weight": 0.4,
"vector_weight": 0.6
}' localhost:50051 memory.MemoryService/HybridSearchCheck topic graph availability.
Request:
message GetTopicGraphStatusRequest {}Response:
message GetTopicGraphStatusResponse {
bool available = 1; // True if graph is ready
int64 topic_count = 2; // Number of topics
int64 relationship_count = 3; // Number of relationships
int64 last_update = 4; // Last update timestamp (epoch ms)
}Example:
grpcurl -plaintext localhost:50051 memory.MemoryService/GetTopicGraphStatusFind topics matching a query.
Request:
message GetTopicsByQueryRequest {
string query = 1; // Search query
int32 limit = 2; // Max results (default 10)
}Response:
message GetTopicsByQueryResponse {
repeated Topic topics = 1; // Matching topics
}Errors:
-
INVALID_ARGUMENT: Empty query -
UNAVAILABLE: Topic graph not available
Example:
grpcurl -plaintext -d '{
"query": "rust memory management",
"limit": 5
}' localhost:50051 memory.MemoryService/GetTopicsByQueryGet topics related to a given topic.
Request:
message GetRelatedTopicsRequest {
string topic_id = 1; // Topic ID to find relations for
repeated RelationshipType relationship_types = 2; // Filter by relationship type
}Response:
message GetRelatedTopicsResponse {
repeated RelatedTopic related = 1; // Related topics with relationship info
}Errors:
-
INVALID_ARGUMENT: Empty topic_id -
NOT_FOUND: Topic does not exist -
UNAVAILABLE: Topic graph not available
Example:
grpcurl -plaintext -d '{
"topic_id": "topic:rust-async",
"relationship_types": ["RELATIONSHIP_TYPE_SIMILAR", "RELATIONSHIP_TYPE_CHILD"]
}' localhost:50051 memory.MemoryService/GetRelatedTopicsGet top topics by importance score with time decay.
Request:
message GetTopTopicsRequest {
int32 limit = 1; // Max results (default 10)
int32 since_days = 2; // Look back window in days (default 30)
}Response:
message GetTopTopicsResponse {
repeated RankedTopic topics = 1; // Topics ranked by importance
}Example:
grpcurl -plaintext -d '{
"limit": 10,
"since_days": 7
}' localhost:50051 memory.MemoryService/GetTopTopicsThe SchedulerService provides management operations for background scheduler jobs.
Proto file: proto/scheduler.proto
List all registered scheduler jobs.
Request:
message ListJobsRequest {}Response:
message ListJobsResponse {
repeated JobInfo jobs = 1; // All registered jobs
}Example:
grpcurl -plaintext localhost:50051 scheduler.SchedulerService/ListJobsGet status of a specific job.
Request:
message GetJobRequest {
string job_name = 1; // Name of the job
}Response:
message GetJobResponse {
JobInfo job = 1; // Job details including status
}Errors:
-
INVALID_ARGUMENT: Empty job_name -
NOT_FOUND: Job does not exist
Example:
grpcurl -plaintext -d '{
"job_name": "segment_summarizer"
}' localhost:50051 scheduler.SchedulerService/GetJobPause a scheduler job.
Request:
message PauseJobRequest {
string job_name = 1; // Name of the job to pause
}Response:
message PauseJobResponse {
bool success = 1; // True if paused successfully
string message = 2; // Status message
}Errors:
-
INVALID_ARGUMENT: Empty job_name -
NOT_FOUND: Job does not exist -
FAILED_PRECONDITION: Job already paused
Example:
grpcurl -plaintext -d '{
"job_name": "segment_summarizer"
}' localhost:50051 scheduler.SchedulerService/PauseJobResume a paused scheduler job.
Request:
message ResumeJobRequest {
string job_name = 1; // Name of the job to resume
}Response:
message ResumeJobResponse {
bool success = 1; // True if resumed successfully
string message = 2; // Status message
}Errors:
-
INVALID_ARGUMENT: Empty job_name -
NOT_FOUND: Job does not exist -
FAILED_PRECONDITION: Job not paused
Example:
grpcurl -plaintext -d '{
"job_name": "segment_summarizer"
}' localhost:50051 scheduler.SchedulerService/ResumeJobenum SearchField {
SEARCH_FIELD_UNSPECIFIED = 0;
SEARCH_FIELD_TITLE = 1;
SEARCH_FIELD_SUMMARY = 2;
SEARCH_FIELD_BULLETS = 3;
SEARCH_FIELD_KEYWORDS = 4;
}| Value | Description |
|---|---|
TITLE |
Search in node titles |
SUMMARY |
Search in summaries |
BULLETS |
Search in bullet text |
KEYWORDS |
Search in keywords |
message SearchMatch {
string field = 1; // Field where match was found
string text = 2; // Matched text
float score = 3; // Match score (0.0-1.0)
repeated string highlights = 4; // Highlighted snippets
}| Field | Type | Description |
|---|---|---|
field |
string | Field name (title, summary, etc.) |
text |
string | Full text of matching content |
score |
float | Match relevance score |
highlights |
string[] | Text snippets with match highlighting |
message NodeMatch {
string node_id = 1; // ID of matching node
TocNode node = 2; // Full node data
repeated SearchMatch matches = 3; // Matches within this node
float aggregate_score = 4; // Combined score for all matches
}| Field | Type | Description |
|---|---|---|
node_id |
string | TOC node identifier |
node |
TocNode | Full node data |
matches |
SearchMatch[] | Individual field matches |
aggregate_score |
float | Combined relevance score |
enum DocType {
DOC_TYPE_UNSPECIFIED = 0;
DOC_TYPE_TOC_NODE = 1;
DOC_TYPE_GRIP = 2;
}| Value | Description |
|---|---|
TOC_NODE |
Table of Contents node |
GRIP |
Provenance anchor |
message TeleportResult {
string doc_id = 1; // Document ID
DocType doc_type = 2; // Document type
string text = 3; // Document text
float bm25_score = 4; // BM25 relevance score
repeated string highlights = 5; // Highlighted snippets
}| Field | Type | Description |
|---|---|---|
doc_id |
string | Unique document identifier |
doc_type |
DocType | Type of document |
text |
string | Document content |
bm25_score |
float | BM25 relevance score |
highlights |
string[] | Highlighted match snippets |
message VectorResult {
string doc_id = 1; // Document ID
DocType doc_type = 2; // Document type
string text = 3; // Document text
float similarity = 4; // Cosine similarity score (0.0-1.0)
}| Field | Type | Description |
|---|---|---|
doc_id |
string | Unique document identifier |
doc_type |
DocType | Type of document |
text |
string | Document content |
similarity |
float | Cosine similarity to query |
message HybridResult {
string doc_id = 1; // Document ID
DocType doc_type = 2; // Document type
string text = 3; // Document text
float combined_score = 4; // RRF combined score
float bm25_score = 5; // BM25 component score
float vector_score = 6; // Vector component score
int32 bm25_rank = 7; // Rank in BM25 results
int32 vector_rank = 8; // Rank in vector results
}| Field | Type | Description |
|---|---|---|
doc_id |
string | Unique document identifier |
doc_type |
DocType | Type of document |
text |
string | Document content |
combined_score |
float | RRF fused score |
bm25_score |
float | BM25 score (if available) |
vector_score |
float | Similarity score (if available) |
bm25_rank |
int32 | Position in BM25 ranking |
vector_rank |
int32 | Position in vector ranking |
message Topic {
string topic_id = 1; // Unique topic identifier
string name = 2; // Topic name
string description = 3; // Topic description
float importance = 4; // Importance score (0.0-1.0)
int64 first_seen = 5; // First occurrence (epoch ms)
int64 last_seen = 6; // Last occurrence (epoch ms)
int32 occurrence_count = 7; // Number of occurrences
}| Field | Type | Description |
|---|---|---|
topic_id |
string | Unique identifier (e.g., "topic:rust-async") |
name |
string | Human-readable topic name |
description |
string | Brief topic description |
importance |
float | Computed importance score |
first_seen |
int64 | First occurrence timestamp |
last_seen |
int64 | Most recent occurrence |
occurrence_count |
int32 | Total occurrence count |
enum RelationshipType {
RELATIONSHIP_TYPE_UNSPECIFIED = 0;
RELATIONSHIP_TYPE_SIMILAR = 1;
RELATIONSHIP_TYPE_CHILD = 2;
RELATIONSHIP_TYPE_PARENT = 3;
RELATIONSHIP_TYPE_SEQUENTIAL = 4;
}| Value | Description |
|---|---|
SIMILAR |
Topics are semantically similar |
CHILD |
Topic is a subtopic |
PARENT |
Topic is a parent topic |
SEQUENTIAL |
Topics often appear in sequence |
message RelatedTopic {
Topic topic = 1; // The related topic
RelationshipType relationship = 2; // Type of relationship
float strength = 3; // Relationship strength (0.0-1.0)
}| Field | Type | Description |
|---|---|---|
topic |
Topic | The related topic |
relationship |
RelationshipType | How topics are related |
strength |
float | Relationship strength |
message RankedTopic {
Topic topic = 1; // The topic
float rank_score = 2; // Time-decayed importance score
int32 rank = 3; // Position in ranking
}| Field | Type | Description |
|---|---|---|
topic |
Topic | The topic |
rank_score |
float | Score with time decay applied |
rank |
int32 | Position in ranking (1-based) |
enum JobStatus {
JOB_STATUS_UNSPECIFIED = 0;
JOB_STATUS_RUNNING = 1;
JOB_STATUS_PAUSED = 2;
JOB_STATUS_IDLE = 3;
JOB_STATUS_ERROR = 4;
}| Value | Description |
|---|---|
RUNNING |
Job is currently executing |
PAUSED |
Job is paused |
IDLE |
Job is waiting for next scheduled run |
ERROR |
Job encountered an error |
message JobInfo {
string name = 1; // Job name
string description = 2; // Job description
JobStatus status = 3; // Current status
string schedule = 4; // Cron schedule expression
int64 last_run = 5; // Last run timestamp (epoch ms)
int64 next_run = 6; // Next scheduled run (epoch ms)
int32 run_count = 7; // Total successful runs
int32 error_count = 8; // Total error runs
optional string last_error = 9; // Last error message (if any)
}| Field | Type | Description |
|---|---|---|
name |
string | Unique job identifier |
description |
string | Human-readable description |
status |
JobStatus | Current job status |
schedule |
string | Cron expression (e.g., "0 */5 * * * *") |
last_run |
int64 | Last execution timestamp |
next_run |
int64 | Next scheduled execution |
run_count |
int32 | Successful execution count |
error_count |
int32 | Failed execution count |
last_error |
string | Most recent error message |
The service exposes a standard gRPC health check endpoint.
grpcurl -plaintext localhost:50051 grpc.health.v1.Health/CheckResponse:
{
"status": "SERVING"
}The service supports gRPC reflection for API discovery.
# List services
grpcurl -plaintext localhost:50051 list
# Describe service
grpcurl -plaintext localhost:50051 describe memory.MemoryService
# Describe message type
grpcurl -plaintext localhost:50051 describe memory.Event