Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions packages/core/src/long-term-memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,41 @@ export interface ApplyMemoryMutationsRequest {
readonly mutations: readonly MemoryItemMutation[];
}

/** Session-wide watermark for the RuntimeEvent coverage already evaluated for long-term memory. */
export interface MemoryExtractionCursor {
readonly sessionId: string;
readonly processedOrdinal: number;
readonly updatedAt: number;
}

export interface MemoryExtractionRequestedItemResult {
readonly itemId: string;
readonly content: string;
}

export interface MemoryExtractionReceipt {
readonly operationId: string;
readonly sessionId: string;
readonly status: 'remembered' | 'not_applicable' | 'extracted';
readonly requestedItems: readonly MemoryExtractionRequestedItemResult[];
readonly committedAt: number;
}

/**
* Trusted extraction commit. Runtime validates the frozen RuntimeEvent boundary before calling
* the Store; SQLite atomically creates admitted Items and advances the Session watermark.
*/
export interface CommitMemoryExtractionRequest {
readonly operationId: string;
readonly sessionId: string;
readonly expectedCursorOrdinal: number;
readonly nextCursorOrdinal: number;
readonly items: readonly MemoryItemWrite[];
/** Indexes into items whose committed identities are observable to memory_remember. */
readonly requestedItemIndexes: readonly number[];
readonly trigger: 'remember' | 'extract';
}

export type MemoryMutationOutcome = 'created' | 'updated' | 'archived' | 'restored' | 'noop';

export interface MemoryMutationResult {
Expand All @@ -163,6 +198,11 @@ export interface MemoryWriteOperationResult {
readonly results: readonly MemoryMutationResult[];
}

export interface MemoryExtractionCommitResult extends MemoryWriteOperationResult {
readonly cursor: MemoryExtractionCursor;
readonly receipt: MemoryExtractionReceipt;
}

export interface MemoryItemRecord {
readonly item: MemoryItem;
readonly keys: readonly MemoryItemKey[];
Expand All @@ -181,6 +221,9 @@ export interface SearchMemoryItemsByKeyRequest {

export interface MemoryItemStore {
applyMutations(request: ApplyMemoryMutationsRequest): Promise<MemoryWriteOperationResult>;
commitExtraction(request: CommitMemoryExtractionRequest): Promise<MemoryExtractionCommitResult>;
readExtractionCursor(sessionId: string): Promise<MemoryExtractionCursor | undefined>;
readExtractionReceipt(operationId: string): Promise<MemoryExtractionReceipt | undefined>;
readItem(itemId: string): Promise<MemoryItemRecord | undefined>;
searchByKeys(request: SearchMemoryItemsByKeyRequest): Promise<readonly MemoryItemRecord[]>;
readOperation(operationId: string): Promise<MemoryWriteOperationResult | undefined>;
Expand All @@ -189,9 +232,8 @@ export interface MemoryItemStore {
export type MemoryItemStoreConflictReason =
| 'operation_reused'
| 'version_conflict'
| 'duplicate_active'
| 'duplicate_within_batch'
| 'item_not_found'
| 'cursor_conflict'
| 'invalid_lifecycle_transition';

export class MemoryItemStoreConflictError extends Error {
Expand All @@ -201,7 +243,6 @@ export class MemoryItemStoreConflictError extends Error {
readonly reason: MemoryItemStoreConflictReason,
message: string,
readonly itemId?: string,
readonly conflictingItemId?: string,
) {
super(message);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/tool-catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export const MAKA_CATALOG_TOOLS: readonly CatalogToolDef[] = Object.freeze(
{ name: 'task_update' },
{ name: 'task_list' },
{ name: 'task_get' },
{ name: 'memory_remember' },
{ name: 'memory_extract' },
// Legacy task-ledger aliases still registered on some hosts
{ name: 'TaskCreate' },
{ name: 'TaskUpdate' },
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/usage-stats/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const MODEL_CALL_KINDS = [
'session_title',
'session_recap',
'daily_review',
'memory_extraction',
] as const;
export type ModelCallKind = (typeof MODEL_CALL_KINDS)[number];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ test('production Host executes a canonical ai-sdk Session against a real provide
'Write',
'WriteStdin',
'load_tools',
'memory_extract',
'memory_remember',
'task_create',
'task_get',
'task_list',
Expand Down
Loading
Loading