Skip to main content

Sagittarius

Sagittarius

Knowledge graph memory for Octopus — entities, relationships, embeddings, and temporal facts.

Knowledge Graph Architecture

SDK Layer
SagittariusClient
SagittariusConfig.from_env()
Modules
graph/
Nodes & Edges Temporal Facts
identity/
Identity Resolution
embedding/
Vector Embeddings
retrieval/
Graph Traversal Similarity Search
sync/
State Sync External Systems
ingest/
Data Ingestion Normalization
Redis DB 1
Graph storage (separate from DB 0 cache)
FalkorDB
Cypher-compatible graph queries
Sample Graph — Nodes & Edges
CREATEDASSIGNED_TOMEMBER_OFREVIEWEDPersonpedro@company.comRepositoryorbit-constellation-apiIssuePROJ-123Teamplatform-engineeringPullRequestPR #42 — merged

All edges carry valid_from / valid_to timestamps for temporal versioning.

What & Why

Sagittarius gives Octopus memory. Every action taken through the API can be traced. Cross-system identities are linked. Documents are stored as graph nodes with vector embeddings for semantic search. This enables GraphRAG: retrieving information by meaning AND by relationship.

Without Sagittarius, Octopus would treat each API call in isolation — no history, no cross-system awareness, no ability to answer "who worked on this PR and what Jira tickets were involved?" With Sagittarius, the platform accumulates knowledge over time. Agents can reason over the graph to surface context that no single API response would provide.

CapabilityHow Sagittarius enables it
Decision tracesrecord_trace() stores action + entity + context as a graph edge with timestamp
Cross-system identityidentity.resolve() maps any system user ID to a canonical Person node
Semantic searchsearch_similar() queries vector embeddings stored alongside graph nodes
Temporal queriesget_entity_timeline() returns versioned facts ordered by valid_from
GraphRAGCombine vector similarity retrieval with Cypher graph traversal in one query

Identity Resolution — One Person, Many Systems

GitHubuser: "pedro"Jirauser: "pferreira"Emailpedro@company.comidentity/SagittariusClient.identity.resolve()canonicalPersonid: "canonical:pedro"github_id · jira_id · emaillinked across all systems

The identity resolver maintains a canonical Person node for every individual regardless of how many system accounts they have. Calling identity.resolve(system="github", external_id="pedro") returns the same canonical entity as resolving the Jira or email representation.

Module Dependency Graph

SagittariusClient (sdk/)
↓ depends on
graph/identity/embedding/retrieval/sync/ingest/
↓ all depend on
storage/ — Redis DB 1 + FalkorDB

Reference

Configuration

VariableDefaultDescription
REDIS_URLredis://localhost:6379Redis connection string
SAGITTARIUS_DB1Redis database index (DB 1 is dedicated to the graph; DB 0 is used for cache)

Load config in code:

from orbit_sagittarius.sdk import SagittariusClient, SagittariusConfig

config = SagittariusConfig.from_env()
client = SagittariusClient(config=config)

Key Methods

client.record_trace(action, entity_id, context)

Store a decision trace edge in the graph.

await client.record_trace(
action="create_issue",
entity_id="jira:PROJ-123",
context={"triggered_by": "agent:orbie", "ts": "2026-05-12T10:00:00Z"},
)

Traces are edges with valid_from set to the current timestamp. They link the acting entity to the target entity under a labeled relationship.


client.identity.resolve(system, external_id)

Resolve an external system user ID to the canonical Person node.

canonical = await client.identity.resolve(
system="github",
external_id="pedro",
)
# Returns: {"canonical_id": "canonical:pedro", "aliases": {...}}

Supported systems: github, jira, slack, email, and any custom system registered via the ingest layer.


client.search_similar(query, top_k, node_type)

Find the most semantically similar graph nodes using vector embeddings.

results = await client.search_similar(
query="authentication middleware refactor",
top_k=5,
node_type="PullRequest",
)
# Returns a ranked list of PullRequest nodes with similarity scores

Embeddings are produced by sentence-transformers and stored alongside each node at ingest time.


client.get_entity_timeline(entity_id)

Return all temporal facts for an entity, ordered by valid_from.

timeline = await client.get_entity_timeline("jira:PROJ-123")
# Returns: list of {fact, valid_from, valid_to, ...} ordered ascending

Facts with valid_to=None are currently active. Expired facts have a non-null valid_to.


Node Types

TypeDescription
PersonA canonical identity linking one or more system accounts
RepositoryA code repository (GitHub, GitLab, etc.)
IssueA work item (Jira, GitHub Issues, Linear, etc.)
PullRequestA code review / merge request
TeamAn organizational group or squad
DocumentA document or page (Notion, Confluence, Google Drive)

Edge Types

EdgeMeaning
CREATEDPerson created entity
ASSIGNED_TOPerson assigned to entity
MEMBER_OFPerson is member of Team
REVIEWEDPerson reviewed PullRequest
REFERENCESEntity references another entity
TAGGEDEntity tagged with a label/category