SDK

SDK API reference

The public API of oortmem 0.6.0: what it exports, every createOort() option, the methods of a handle and the shapes they return.

The SDK's shapecreateOort(options) returns an Oort handle whose scope is fixed. Its methods return plain typed results, and every failure is an OortError.createOort()optionsOorta handle, scope fixedResultstyped, or OortError

Exports

ImportExports
oortmemcreateOort, formatForPrompt, VERSION, the error classes (SDK errors) and every type on this page.
oortmem/ai-sdkoortTools, oortObserve, oortInstructions. Experimental (SDK in agent frameworks).

Deep imports such as oortmem/dist/… are blocked by the package's exports map.

createOort(options?)

Async, and returns an Oort handle. It makes no network request. Every option object is checked strictly: an unknown key, or an option the mode does not take, throws OortUsageError. Nothing is silently ignored.

mode
Type'auto' | 'local' | 'cloud'
Modesall
Default'auto': what setup chose, else local
home
Typestring
Modeslocal, auto
DefaultOORT_HOME, else ~/.oort
cwd
Typestring
Modesall
Defaultprocess.cwd(); only finds the project and its config
project
Typestring | null
Modesall
DefaultDerived from cwd as the CLI does. A string becomes cfg:<id>; null means global memories only
projectConfig
Typeboolean
Modeslocal, cloud
Defaulttrue. false skips the repository's oort.config.json
agent
Typestring
Modesall
DefaultOORT_AGENT, else anonymous (the Planet only)
user
Typestring
Modeslocal
DefaultUnset: the person. Setting it requires org
org
Typestring
Modeslocal
Default'local'. Required, and not 'local', with user
keys
Type{ voyage?, typesafe?, anthropic?, oort? }
Modeslocal; cloud (oort only)
Defaultnone
keySources
Type('explicit' | 'env' | 'keychain')[]
Modesall
DefaultAll three; keychain is skipped with OORT_NO_KEYCHAIN=1
config
TypeA deep partial of the home config
Modeslocal
DefaultNone. serve cannot be set
url
Typestring
Modescloud
DefaultOORT_CLOUD_URL, else https://api.oortcloud.dev
timeoutMs
Typenumber
Modescloud
Default30,000 per request
migrate
Typeboolean
Modeslocal
Defaulttrue. false refuses an older store
env
TypeRecord<string, string | undefined>
Modesall
Defaultprocess.env
fetch
Typetypeof fetch
Modescloud
DefaultA keep-alive connection pool
judge
Type{ role: 'agent' | 'expert'; operator?: string }
Modeslocal
Default{ role: 'agent' }

Each model role (embed, rerank, decide, write) uses the first key found: keys, then the vendor's environment variable, then the Keychain, then the Oort key through the Oort Pro relay. See Running in your own infrastructure for servers.

The handle

TypeScript
interface Oort {
  readonly mode: 'local' | 'cloud';
  readonly judge: OortJudge;
  recall(query: string, opts?: RecallOptions): Promise<RecallResult>;
  observe(turn: Turn, opts?: { signal?: AbortSignal }): Promise<ObserveResult>;
  remember(facts: string | readonly string[], opts?: { type?: MemoryType }): Promise<RememberResult>;
  forget(id: string, opts?: { everywhere?: boolean }): Promise<ForgetResult>;
  pin(id: string): Promise<PinResult>;
  unpin(id: string): Promise<PinResult>;
  recent(opts?: { since?: string | Date; limit?: number }): Promise<{ memories: MemoryView[]; warnings: Warning[] }>;
  explain(id: string): Promise<Explanation>;
  whoami(): Promise<Whoami>;
  consolidate(opts?: { budgetMs?: number; signal?: AbortSignal }): Promise<ConsolidateResult>;
  scoped(s: ScopedOptions): Oort;
  close(): Promise<void>;
  [Symbol.asyncDispose](): Promise<void>;
}

interface OortJudge {
  record(input: JudgmentInput): Promise<RecordJudgmentView>;
  apply(item: string | JudgeItem, opts?: JudgeOptions): Promise<JudgeResult>;
  list(opts?: { domain?: string; by?: string; all?: boolean; limit?: number }): Promise<{ judgments: (JudgmentView & { id: string })[] }>;
  confirm(id: string): Promise<{ id: string; changed: boolean }>;
}
recall, observe, remember, pin, unpin, recent, explain, whoami
Localyes
Cloudyes
forget
Localyes
Cloudyes; everywhere is cloud only
judge.record, judge.apply, judge.list
Localyes
Cloudrefused (local-only)
judge.confirm
Localexpert role only
Cloudrefused (local-only)
consolidate
Localyes
Cloudrefused (local-only)
scoped
Localyes
Cloudproject and agent only
  • Ids. A full id, or a unique prefix of at least 8 characters. Several matches throw OortAmbiguousIdError. An id outside the handle's scope is OortNotFoundError, exactly like an unknown one.
  • Concurrency. One handle is safe for concurrent calls.
  • Lifecycle. close() is idempotent; afterwards every call throws OortUsageError (closed). A handle from scoped() shares its root's engine: closing it does nothing, and closing the root closes everything. await using closes it for you.
  • observe runs the full write path and can take seconds: call it after answering. remember frames each fact as the user's statement.

recall options

limit
Typenumber
What it does1 to 50, default 10.
mode
Type'current' | 'as-of' | 'history' | 'known-at'
What it doesThe time view. as-of needs asOf, known-at needs knownAt.
asOf
Typestring | Date
What it doesValid time: what was true then.
knownAt
Typestring | Date
What it doesTransaction time: what was known then. Not together with asOf.
include
TypeIncludeLevel[]
What it doesNarrows the levels read: self, planet, star, constellation, galaxy.
budgetChars
Typenumber
What it doesThe default block size for formatForPrompt.
includeWithdrawn
Typeboolean
What it doesAlso withdrawn memories.
speed
Type'full' | 'fast' | 'lexical'
What it doesfull: embed and rerank. fast: no rerank. lexical: no model call.
inferTime
Typeboolean
What it doesDefault true: "on 2 April" picks as-of, as the CLI does.
signal
TypeAbortSignal
What it doesStops waiting and rejects with its reason.

Inputs

TypeScript
interface Turn {
  user: string;
  assistant: string;
  tools?: string[];
  at?: string | Date;
  sessionId?: string;
  turnRef?: string;
}

interface ScopedOptions {
  user?: string;
  project?: string | null;
  agent?: string;
  judgeRole?: 'agent';
}
TypeScript
interface JudgmentInput {
  subject: string;
  ref?: string;
  verdict: string;
  verdicts?: readonly string[];
  reason: string;
  criteria?: readonly string[];
  domain: string;
  by: string;
  decidedAt?: string | Date;
}

interface JudgeItem {
  summary: string;
  details?: string;
  ref?: string;
  domain?: string;
  by?: string;
}

interface JudgeOptions {
  limit?: number;
  threshold?: number;
  minSimilarity?: number;
  minAgreement?: number;
  includeImported?: boolean;
  includeAgentRecorded?: boolean;
}

formatForPrompt(result, opts?)

A function, not a method: formatForPrompt(result, { budgetChars }) returns the <oort-memory> block as a string, 6,000 characters at most by default. It escapes every memory, so a stored memory can neither close the block nor forge a label.

Results

Plain objects. Ignore fields you do not know: new ones may appear in any release. Every memory's text is scrubbed of secrets again on the way out.

Recall

TypeScript
interface RecallResult {
  memories: RecalledMemory[];
  abstained: boolean;
  temporal: { mode: RecallMode; asOf?: string; knownAt?: string; inferred: boolean };
  read: string[];
  degraded: string[];
  warnings: Warning[];
}

interface MemoryView {
  id: string;
  text: string;
  type: MemoryType;
  tier: 'hot' | 'warm' | 'cold';
  pinned: boolean;
  status: MemoryStatus;
  validFrom: string;
  validTo: string | null;
  recordedAt: string;
  updatedAt: string;
  entities: string[];
  origin?: { level: IncludeLevel; space: string; author?: string; overriddenBy?: string };
  judgment?: JudgmentView & { id: string };
}

interface RecalledMemory extends MemoryView {
  score: number;
  stale?: true;
  why: { lexicalRank?: number; denseRank?: number; reranked?: number; coverage: number; dense?: number; activation: number; chain?: true }; // experimental
}

interface Warning {
  code: string;
  message: string;
}

Writes and housekeeping

TypeScript
interface ObserveResult {
  outcome: Outcome;
  memories: { outcome: Outcome; id?: string; supersedes?: string; reason?: string }[];
  counts: Partial<Record<Outcome, number>>;
  duplicate?: true;
  warnings: Warning[];
}

interface RememberResult {
  results: { fact: number; outcome: Outcome; id?: string; supersedes?: string; reason?: string }[];
  warnings: Warning[];
}

interface ForgetResult {
  forgotten: string;
  withdrawn?: string[];
}

interface PinResult {
  id: string;
  pinned: boolean;
  changed: boolean | null;
}

interface ConsolidateResult {
  promoted: string[];
  demoted: string[];
  evicted: string[];
  expired: string[];
  skipped: number;
  complete: boolean;
}

Explain and whoami

TypeScript
interface Explanation {
  memory: MemoryView & { salience: number; activation: number; source: string };
  decisions: { stage: string; question: string; answer: string; probability: number }[];
  chain: { id: string; text: string; validFrom: string; validTo: string | null; endReason: 'superseded' | 'corrected' | 'expired' | null }[];
  hiddenLinks: number;
}

interface Whoami {
  mode: 'local' | 'cloud';
  account: string | null;
  agent: string | null;
  project: string | null;
  user: string | null;
  reads: string[];
  writesTo: string;
  version: string;
  routes: Record<'embed' | 'rerank' | 'decide' | 'write', RouteKind>;
}

Judgments

TypeScript
interface RecordJudgmentView {
  outcome: 'added' | 'corrected' | 'unchanged';
  id: string;
  corrects?: string;
  status: 'agent-recorded' | 'recorded';
  redacted: string[];
  embedFailed?: true;
}

interface JudgeResult {
  status: 'suggested' | 'needs-expert' | 'precedents-only';
  why?: 'no-precedents' | 'too-far' | 'too-few' | 'precedents-disagree' | 'low-confidence' | 'no-decider' | 'decider-failed';
  prediction?: { verdict: string; probability: number; probabilities: Record<string, number> };
  precedents: Precedent[];
  verdicts: string[];
  agreement: Record<string, number>;
  similarity: 'dense' | 'lexical';
  threshold: number;
  minSimilarity: number;
  degraded?: string[];
  decisions: { stage: string; question: string; answer: string; probability: number }[]; // experimental
  importedExcluded?: number;
  agentRecordedExcluded?: number;
}

interface Precedent {
  id: string;
  subject: { summary: string; ref?: string };
  verdict: string;
  reason: string;
  criteria: string[];
  domain: string;
  by: string;
  decidedAt: string;
  similarity: number;
  near: boolean;
  agrees?: boolean;
  via: JudgmentVia;
  confirmed: boolean;
  agentRecorded: boolean;
  pack?: { id: string; name: string };
}

interface JudgmentView {
  subject: { summary: string; ref?: string };
  verdict: string;
  verdicts: string[];
  reason: string;
  criteria: string[];
  domain: string;
  by: string;
  decidedAt: string;
  via: JudgmentVia;
  status: MemoryStatus;
  confirmed: boolean;
  agentRecorded: boolean;
  withdrawn?: { at: string; by: string };
  pack?: { id: string; name: string };
}

String values

TypeValues
MemoryTypesemantic, episodic, procedural, preference, judgment
MemoryStatuscurrent, superseded, corrected, expired, not-yet-valid, withdrawn
Outcomeadded, reinforced, updated, superseded, corrected, skipped
IncludeLevelself, planet, star, constellation, galaxy
RecallModecurrent, as-of, history, known-at
JudgmentViacli, mcp, import, pack, sdk
RouteKindown-key, oort-pro, local, cloud, missing

Reserved names

place (on turns, remember and memory views), near and within (on recall) are reserved for spatial memory. Passing any of them today is a usage error, never a silent drop.