Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const client = new DakeraClient({

// Cloud (early access)
const client = new DakeraClient({
baseUrl: 'http://localhost:3000',
baseUrl: 'http://<your-server-ip>:3000',
apiKey: 'your-key',
});

Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dakera-ai/dakera",
"version": "0.11.56",
"version": "0.11.57",
"description": "TypeScript/JavaScript SDK for Dakera AI memory platform",
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand Down
38 changes: 38 additions & 0 deletions src/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,44 @@ describe('DakeraClient', () => {
});
});

// ---------------------------------------------------------------------------
// DAK-5508: Batch Store Memory
// ---------------------------------------------------------------------------

describe('storeMemoriesBatch', () => {
it('POSTs to /v1/memories/store/batch and returns BatchStoreMemoryResponse', async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
status: 200,
headers: new Headers({ 'content-type': 'application/json' }),
json: async () => ({
stored: [
{ id: 'mem-1', content: 'Dark mode', agent_id: 'agent-1', tags: [], importance: 0.8, created_at: 1700000000 },
{ id: 'mem-2', content: 'Berlin user', agent_id: 'agent-1', tags: [], importance: 0.7, created_at: 1700000001 },
],
stored_count: 2,
total_embedding_time_ms: 42,
}),
});

const resp = await client.storeMemoriesBatch({
agent_id: 'agent-1',
memories: [
{ content: 'Dark mode', importance: 0.8 },
{ content: 'Berlin user', importance: 0.7 },
],
});

expect(resp.stored_count).toBe(2);
expect(resp.stored).toHaveLength(2);
expect(resp.stored[0].id).toBe('mem-1');
expect(resp.total_embedding_time_ms).toBe(42);
const [url, init] = mockFetch.mock.calls[0];
expect(url).toContain('/v1/memories/store/batch');
expect(init?.method).toBe('POST');
});
});

// ---------------------------------------------------------------------------
// OPS-1: Rate-Limit Headers (v0.7.0)
// ---------------------------------------------------------------------------
Expand Down
25 changes: 25 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ import type {
BatchRecallResponse,
BatchForgetRequest,
BatchForgetResponse,
BatchStoreMemoryRequest,
BatchStoreMemoryResponse,
RateLimitHeaders,
AutoPilotStatusResponse,
AutoPilotConfigRequest,
Expand Down Expand Up @@ -1537,6 +1539,29 @@ export class DakeraClient {
return this.request<BatchForgetResponse>('DELETE', '/v1/memories/forget/batch', request);
}

/**
* Store multiple memories in a single request (DAK-5508).
*
* Uses `POST /v1/memories/store/batch`. The server embeds all contents in a
* single ONNX inference pass, yielding ≥100× throughput vs. N sequential
* single-store calls. Accepts up to 1 000 memories per call.
*
* @example
* ```ts
* const resp = await client.storeMemoriesBatch({
* agent_id: 'agent-1',
* memories: [
* { content: 'The user prefers dark mode', importance: 0.8 },
* { content: 'The user is based in Berlin', importance: 0.7 },
* ],
* });
* console.log(`Stored ${resp.stored_count} memories`);
* ```
*/
async storeMemoriesBatch(request: BatchStoreMemoryRequest): Promise<BatchStoreMemoryResponse> {
return this.request<BatchStoreMemoryResponse>('POST', '/v1/memories/store/batch', request);
}

/** Search memories for an agent */
async searchMemories(agentId: string, query: string, options?: { top_k?: number; memory_type?: string; min_importance?: number; routing?: import('./types').RoutingMode; rerank?: boolean }): Promise<RecalledMemory[]> {
const body: Record<string, unknown> = { query };
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export type {
BatchRecallResponse,
BatchForgetRequest,
BatchForgetResponse,
BatchStoreMemoryItem,
BatchStoreMemoryRequest,
BatchStoreMemoryResponse,
BatchStoredMemory,
// Rate-limit headers (OPS-1)
RateLimitHeaders,
// Session types
Expand Down
64 changes: 64 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1654,6 +1654,70 @@ export interface BatchForgetResponse {
deleted_count: number;
}

// ============================================================================
// Batch Store Memory Types (DAK-5508)
// ============================================================================

/**
* A single memory entry within a {@link BatchStoreMemoryRequest}.
*
* Mirrors `StoreMemoryRequest` but omits `agent_id` — supplied at batch level.
*/
export interface BatchStoreMemoryItem {
/** Memory content text (required, max 100 000 chars). */
content: string;
/** One of `"episodic"`, `"semantic"`, `"procedural"`, or `"working"`. */
memory_type?: MemoryType;
/** Importance score 0.0–1.0 (default: 0.5). */
importance?: number;
/** Optional tags to associate with the memory. */
tags?: string[];
/** Optional session ID to associate with. */
session_id?: string;
/** Arbitrary metadata dictionary. */
metadata?: Record<string, unknown>;
/** Optional TTL in seconds. */
ttl_seconds?: number;
/** Optional explicit expiry as a Unix timestamp (seconds). */
expires_at?: number;
/** Optional custom ID. Auto-generated if not provided. */
id?: string;
}

/**
* Request body for `POST /v1/memories/store/batch` (DAK-5508).
*
* Accepts up to 1 000 memories per call. The server embeds all contents in a
* single ONNX inference pass, yielding ≥100× throughput vs. N sequential
* single-store calls.
*/
export interface BatchStoreMemoryRequest {
/** Agent namespace to store the memories in. */
agent_id: string;
/** Memories to store (1–1000 items). */
memories: BatchStoreMemoryItem[];
}

/** A single stored memory returned in a {@link BatchStoreMemoryResponse}. */
export interface BatchStoredMemory {
id: string;
content: string;
agent_id: string;
tags: string[];
importance: number;
created_at: number;
}

/** Response from `POST /v1/memories/store/batch`. */
export interface BatchStoreMemoryResponse {
/** Stored memories in the same order as the request items. */
stored: BatchStoredMemory[];
/** Number of memories successfully stored. */
stored_count: number;
/** Time spent on ONNX embedding for the entire batch (milliseconds). */
total_embedding_time_ms: number;
}

// ============================================================================
// Memory Knowledge Graph Types (CE-5 / SDK-9)
// ============================================================================
Expand Down
Loading