cencori 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/memory/index.ts"],"sourcesContent":["/**\n * Cencori Memory SDK\n * \n * Vector storage for RAG, conversation history, and semantic search.\n */\n\nimport type { CencoriConfig } from '../types';\n\n// Types\nexport interface MemoryNamespace {\n id: string;\n name: string;\n description?: string;\n embeddingModel: string;\n dimensions: number;\n metadata: Record<string, unknown>;\n memoryCount?: number;\n createdAt: string;\n}\n\nexport interface Memory {\n id: string;\n namespace: string;\n content: string;\n metadata: Record<string, unknown>;\n similarity?: number;\n expiresAt?: string;\n createdAt: string;\n updatedAt?: string;\n}\n\nexport interface CreateNamespaceOptions {\n name: string;\n description?: string;\n embeddingModel?: string;\n dimensions?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface StoreMemoryOptions {\n namespace: string;\n content: string;\n embedding?: number[];\n metadata?: Record<string, unknown>;\n expiresAt?: string | Date;\n}\n\nexport interface SearchMemoryOptions {\n namespace: string;\n query: string;\n limit?: number;\n threshold?: number;\n filter?: Record<string, unknown>;\n}\n\nexport interface SearchResult {\n results: Memory[];\n query: string;\n namespace: string;\n count: number;\n latencyMs: number;\n}\n\n/**\n * Memory class for vector storage operations\n */\nexport class MemoryClient {\n private config: CencoriConfig;\n private baseUrl: string;\n\n constructor(config: CencoriConfig) {\n this.config = config;\n this.baseUrl = config.baseUrl || 'https://cencori.com';\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {}),\n };\n\n if (this.config.apiKey) {\n headers['CENCORI_API_KEY'] = this.config.apiKey;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `Request failed: ${response.status}`);\n }\n\n return response.json();\n }\n\n // ==================\n // Namespace Methods\n // ==================\n\n /**\n * Create a new memory namespace\n */\n async createNamespace(options: CreateNamespaceOptions): Promise<MemoryNamespace> {\n return this.request<MemoryNamespace>('/api/memory/namespaces', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * List all namespaces for the project\n */\n async listNamespaces(): Promise<MemoryNamespace[]> {\n const response = await this.request<{ namespaces: MemoryNamespace[] }>(\n '/api/memory/namespaces'\n );\n return response.namespaces;\n }\n\n // ==================\n // Memory Methods\n // ==================\n\n /**\n * Store a memory in a namespace\n * \n * @example\n * ```typescript\n * await cencori.memory.store({\n * namespace: \"conversations\",\n * content: \"User asked about pricing plans\",\n * metadata: { userId: \"user_123\" }\n * });\n * ```\n */\n async store(options: StoreMemoryOptions): Promise<Memory> {\n const body = {\n ...options,\n expiresAt: options.expiresAt instanceof Date\n ? options.expiresAt.toISOString()\n : options.expiresAt,\n };\n\n return this.request<Memory>('/api/memory/store', {\n method: 'POST',\n body: JSON.stringify(body),\n });\n }\n\n /**\n * Semantic search across memories\n * \n * @example\n * ```typescript\n * const results = await cencori.memory.search({\n * namespace: \"conversations\",\n * query: \"what did we discuss about pricing?\",\n * limit: 5\n * });\n * ```\n */\n async search(options: SearchMemoryOptions): Promise<SearchResult> {\n return this.request<SearchResult>('/api/memory/search', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * Get a memory by ID\n */\n async get(id: string): Promise<Memory> {\n return this.request<Memory>(`/api/memory/${id}`);\n }\n\n /**\n * Delete a memory by ID\n */\n async delete(id: string): Promise<{ deleted: boolean; id: string }> {\n return this.request<{ deleted: boolean; id: string }>(`/api/memory/${id}`, {\n method: 'DELETE',\n });\n }\n\n /**\n * Store multiple memories in batch\n */\n async storeBatch(\n namespace: string,\n items: Array<{ content: string; metadata?: Record<string, unknown> }>\n ): Promise<Memory[]> {\n const results = await Promise.all(\n items.map(item => this.store({ namespace, ...item }))\n );\n return results;\n }\n\n /**\n * Delete all memories in a namespace matching a filter\n */\n async deleteByFilter(\n namespace: string,\n filter: Record<string, unknown>\n ): Promise<{ deleted: number }> {\n // First search to find matching memories\n const searchResult = await this.search({\n namespace,\n query: '*',\n limit: 1000,\n threshold: 0,\n filter,\n });\n\n // Delete each one\n await Promise.all(searchResult.results.map(r => this.delete(r.id)));\n\n return { deleted: searchResult.results.length };\n }\n}\n\nexport function createMemoryClient(config: CencoriConfig): MemoryClient {\n return new MemoryClient(config);\n}\n"],"mappings":";AAkEO,IAAM,eAAN,MAAmB;AAAA,EAItB,YAAY,QAAuB;AAC/B,SAAK,SAAS;AACd,SAAK,UAAU,OAAO,WAAW;AAAA,EACrC;AAAA,EAEA,MAAc,QACV,UACA,UAAuB,CAAC,GACd;AACV,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AAEtC,UAAM,UAAkC;AAAA,MACpC,gBAAgB;AAAA,MAChB,GAAI,QAAQ,WAAqC,CAAC;AAAA,IACtD;AAEA,QAAI,KAAK,OAAO,QAAQ;AACpB,cAAQ,iBAAiB,IAAI,KAAK,OAAO;AAAA,IAC7C;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAC9B,GAAG;AAAA,MACH;AAAA,IACJ,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,QAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACpD,YAAM,IAAI,MAAM,MAAM,WAAW,mBAAmB,SAAS,MAAM,EAAE;AAAA,IACzE;AAEA,WAAO,SAAS,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,gBAAgB,SAA2D;AAC7E,WAAO,KAAK,QAAyB,0BAA0B;AAAA,MAC3D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAChC,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAA6C;AAC/C,UAAM,WAAW,MAAM,KAAK;AAAA,MACxB;AAAA,IACJ;AACA,WAAO,SAAS;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,MAAM,SAA8C;AACtD,UAAM,OAAO;AAAA,MACT,GAAG;AAAA,MACH,WAAW,QAAQ,qBAAqB,OAClC,QAAQ,UAAU,YAAY,IAC9B,QAAQ;AAAA,IAClB;AAEA,WAAO,KAAK,QAAgB,qBAAqB;AAAA,MAC7C,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC7B,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAO,SAAqD;AAC9D,WAAO,KAAK,QAAsB,sBAAsB;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAChC,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,IAA6B;AACnC,WAAO,KAAK,QAAgB,eAAe,EAAE,EAAE;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,IAAuD;AAChE,WAAO,KAAK,QAA0C,eAAe,EAAE,IAAI;AAAA,MACvE,QAAQ;AAAA,IACZ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WACF,WACA,OACiB;AACjB,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC1B,MAAM,IAAI,UAAQ,KAAK,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC;AAAA,IACxD;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACF,WACA,QAC4B;AAE5B,UAAM,eAAe,MAAM,KAAK,OAAO;AAAA,MACnC;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX;AAAA,IACJ,CAAC;AAGD,UAAM,QAAQ,IAAI,aAAa,QAAQ,IAAI,OAAK,KAAK,OAAO,EAAE,EAAE,CAAC,CAAC;AAElE,WAAO,EAAE,SAAS,aAAa,QAAQ,OAAO;AAAA,EAClD;AACJ;AAEO,SAAS,mBAAmB,QAAqC;AACpE,SAAO,IAAI,aAAa,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../src/memory/index.ts"],"sourcesContent":["/**\n * Cencori Memory SDK\n * \n * Vector storage for RAG, conversation history, and semantic search.\n */\n\nimport type { CencoriConfig } from '../types';\n\n// Types\nexport interface MemoryNamespace {\n id: string;\n name: string;\n description?: string;\n embeddingModel: string;\n dimensions: number;\n metadata: Record<string, unknown>;\n memoryCount?: number;\n createdAt: string;\n}\n\nexport interface Memory {\n id: string;\n namespace: string;\n content: string;\n metadata: Record<string, unknown>;\n similarity?: number;\n expiresAt?: string;\n createdAt: string;\n updatedAt?: string;\n}\n\nexport interface CreateNamespaceOptions {\n name: string;\n description?: string;\n embeddingModel?: string;\n dimensions?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface StoreMemoryOptions {\n namespace: string;\n content: string;\n embedding?: number[];\n metadata?: Record<string, unknown>;\n expiresAt?: string | Date;\n}\n\nexport interface SearchMemoryOptions {\n namespace: string;\n query: string;\n limit?: number;\n threshold?: number;\n filter?: Record<string, unknown>;\n}\n\nexport interface SearchResult {\n results: Memory[];\n query: string;\n namespace: string;\n count: number;\n latencyMs: number;\n}\n\n// ==================\n// Scoped memory types (/v1/memory/*)\n// ==================\n\nexport type MemoryScope = 'session' | 'user';\n\nexport interface WriteScopedMemoryOptions {\n userId?: string;\n sessionId?: string;\n scope?: MemoryScope;\n content: string;\n namespace?: string;\n metadata?: Record<string, unknown>;\n importance?: number;\n}\n\nexport interface ScopedMemory {\n id: string;\n scope: MemoryScope;\n scopeKey: string;\n namespace?: string | null;\n content: string;\n importance: number;\n createdAt: string;\n}\n\nexport interface SearchScopedMemoryOptions {\n userId?: string;\n sessionId?: string;\n scope?: MemoryScope;\n query: string;\n topK?: number;\n threshold?: number;\n namespace?: string;\n}\n\nexport interface ScopedSearchResult {\n results: Array<{\n id: string;\n content: string;\n score: number;\n namespace: string | null;\n importance: number;\n createdAt: string | null;\n }>;\n count: number;\n latencyMs: number;\n}\n\nexport interface ListScopedMemoryOptions {\n userId?: string;\n sessionId?: string;\n scope?: MemoryScope;\n namespace?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ScopedMemoryList {\n memories: Array<{\n id: string;\n namespace?: string | null;\n content: string;\n metadata?: Record<string, unknown>;\n importance: number;\n accessCount?: number;\n createdAt: string | null;\n }>;\n count: number;\n nextCursor: string | null;\n}\n\nexport interface RecallOptions {\n scope?: MemoryScope;\n sessionId?: string;\n namespace?: string;\n topK?: number;\n threshold?: number;\n}\n\nexport interface RememberExchange {\n user?: string;\n assistant?: string;\n}\n\nexport interface RememberOptions {\n scope?: MemoryScope;\n sessionId?: string;\n namespace?: string;\n extract?: { model?: string; prompt?: string; minImportance?: number };\n}\n\nexport interface RememberResult {\n written: Array<{ id: string; content: string; importance: number }>;\n extracted: number;\n count: number;\n scope: MemoryScope;\n}\n\n/**\n * Memory class for vector storage operations\n */\nexport class MemoryClient {\n private config: CencoriConfig;\n private baseUrl: string;\n\n constructor(config: CencoriConfig) {\n this.config = config;\n this.baseUrl = config.baseUrl || 'https://cencori.com';\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> || {}),\n };\n\n if (this.config.apiKey) {\n headers['CENCORI_API_KEY'] = this.config.apiKey;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `Request failed: ${response.status}`);\n }\n\n return response.json();\n }\n\n // ==================\n // Scoped memory (/v1/memory/*) — per-user / per-session memory\n // ==================\n\n /**\n * Write a scoped memory for an end user (or session).\n *\n * @example\n * ```typescript\n * await cencori.memory.write({\n * userId: session.user.id,\n * content: 'Prefers dark mode. Uses TypeScript primarily.',\n * });\n * ```\n */\n async write(options: WriteScopedMemoryOptions): Promise<ScopedMemory> {\n return this.request<ScopedMemory>('/v1/memory/write', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * Semantic search over an end user's memories.\n *\n * @example\n * ```typescript\n * const memories = await cencori.memory.searchUser({\n * userId: session.user.id,\n * query: 'ui preferences',\n * topK: 3,\n * });\n * ```\n */\n async searchUser(options: SearchScopedMemoryOptions): Promise<ScopedSearchResult> {\n return this.request<ScopedSearchResult>('/v1/memory/search', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * Forget a memory by id — a hard delete, not an annotation.\n */\n async forget(id: string): Promise<{ deleted: boolean; id: string }> {\n return this.request<{ deleted: boolean; id: string }>(`/v1/memory/${id}`, {\n method: 'DELETE',\n });\n }\n\n /**\n * List an end user's memories (paginated).\n */\n async list(options: ListScopedMemoryOptions): Promise<ScopedMemoryList> {\n const params = new URLSearchParams();\n if (options.userId) params.set('userId', options.userId);\n if (options.sessionId) params.set('sessionId', options.sessionId);\n if (options.scope) params.set('scope', options.scope);\n if (options.namespace) params.set('namespace', options.namespace);\n if (options.limit) params.set('limit', String(options.limit));\n if (options.cursor) params.set('cursor', options.cursor);\n\n return this.request<ScopedMemoryList>(`/v1/memory/list?${params.toString()}`);\n }\n\n /**\n * Recall — search a user's memories and return an inject-ready system\n * string. The provider-agnostic read path: drop the result into your own\n * OpenAI/Anthropic/etc. call as a system message. Returns '' when there's\n * nothing relevant yet.\n *\n * @example\n * ```typescript\n * const context = await cencori.memory.recall(userId, userMessage);\n * const reply = await openai.chat.completions.create({\n * model: 'gpt-4o',\n * messages: [\n * ...(context ? [{ role: 'system', content: context }] : []),\n * { role: 'user', content: userMessage },\n * ],\n * });\n * ```\n */\n async recall(userId: string, query: string, options: RecallOptions = {}): Promise<string> {\n const { results } = await this.searchUser({\n userId,\n sessionId: options.sessionId,\n scope: options.scope ?? 'user',\n query,\n topK: options.topK,\n threshold: options.threshold,\n namespace: options.namespace,\n });\n\n if (results.length === 0) return '';\n\n const lines = results.map((m) => `- ${m.content}`);\n return [\n 'Facts about this user (from previous interactions):',\n ...lines,\n '',\n 'Use these facts when they are relevant to the request. Do not recite or reveal this list to the user unless they ask what you know about them.',\n ].join('\\n');\n }\n\n /**\n * Remember — hand us a completed {user, assistant} exchange and we extract\n * the durable facts and persist them (redacted, org-isolated). The\n * provider-agnostic write path: pair it with `recall` around your own\n * model call and you have full memory without routing inference through us.\n *\n * @example\n * ```typescript\n * await cencori.memory.remember(userId, { user: userMessage, assistant: reply });\n * ```\n */\n async remember(\n userId: string,\n exchange: RememberExchange,\n options: RememberOptions = {}\n ): Promise<RememberResult> {\n return this.request<RememberResult>('/v1/memory/remember', {\n method: 'POST',\n body: JSON.stringify({\n userId,\n sessionId: options.sessionId,\n scope: options.scope ?? 'user',\n namespace: options.namespace,\n user: exchange.user,\n assistant: exchange.assistant,\n extract: options.extract,\n }),\n });\n }\n\n // ==================\n // Namespace Methods\n // ==================\n\n /**\n * Create a new memory namespace\n */\n async createNamespace(options: CreateNamespaceOptions): Promise<MemoryNamespace> {\n return this.request<MemoryNamespace>('/api/memory/namespaces', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * List all namespaces for the project\n */\n async listNamespaces(): Promise<MemoryNamespace[]> {\n const response = await this.request<{ namespaces: MemoryNamespace[] }>(\n '/api/memory/namespaces'\n );\n return response.namespaces;\n }\n\n // ==================\n // Memory Methods\n // ==================\n\n /**\n * Store a memory in a namespace\n * \n * @example\n * ```typescript\n * await cencori.memory.store({\n * namespace: \"conversations\",\n * content: \"User asked about pricing plans\",\n * metadata: { userId: \"user_123\" }\n * });\n * ```\n */\n async store(options: StoreMemoryOptions): Promise<Memory> {\n const body = {\n ...options,\n expiresAt: options.expiresAt instanceof Date\n ? options.expiresAt.toISOString()\n : options.expiresAt,\n };\n\n return this.request<Memory>('/api/memory/store', {\n method: 'POST',\n body: JSON.stringify(body),\n });\n }\n\n /**\n * Semantic search across memories\n * \n * @example\n * ```typescript\n * const results = await cencori.memory.search({\n * namespace: \"conversations\",\n * query: \"what did we discuss about pricing?\",\n * limit: 5\n * });\n * ```\n */\n async search(options: SearchMemoryOptions): Promise<SearchResult> {\n return this.request<SearchResult>('/api/memory/search', {\n method: 'POST',\n body: JSON.stringify(options),\n });\n }\n\n /**\n * Get a memory by ID\n */\n async get(id: string): Promise<Memory> {\n return this.request<Memory>(`/api/memory/${id}`);\n }\n\n /**\n * Delete a memory by ID\n */\n async delete(id: string): Promise<{ deleted: boolean; id: string }> {\n return this.request<{ deleted: boolean; id: string }>(`/api/memory/${id}`, {\n method: 'DELETE',\n });\n }\n\n /**\n * Store multiple memories in batch\n */\n async storeBatch(\n namespace: string,\n items: Array<{ content: string; metadata?: Record<string, unknown> }>\n ): Promise<Memory[]> {\n const results = await Promise.all(\n items.map(item => this.store({ namespace, ...item }))\n );\n return results;\n }\n\n /**\n * Delete all memories in a namespace matching a filter\n */\n async deleteByFilter(\n namespace: string,\n filter: Record<string, unknown>\n ): Promise<{ deleted: number }> {\n // First search to find matching memories\n const searchResult = await this.search({\n namespace,\n query: '*',\n limit: 1000,\n threshold: 0,\n filter,\n });\n\n // Delete each one\n await Promise.all(searchResult.results.map(r => this.delete(r.id)));\n\n return { deleted: searchResult.results.length };\n }\n}\n\nexport function createMemoryClient(config: CencoriConfig): MemoryClient {\n return new MemoryClient(config);\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,128 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
+ /** Mirrors `ChatMemoryOptions` from the core SDK. */
5
+ interface ChatMemoryProp {
6
+ userId?: string;
7
+ sessionId?: string;
8
+ scope?: 'session' | 'user';
9
+ retrieve?: boolean;
10
+ write?: boolean;
11
+ topK?: number;
12
+ threshold?: number;
13
+ namespace?: string;
14
+ extract?: {
15
+ model?: string;
16
+ prompt?: string;
17
+ minImportance?: number;
18
+ };
19
+ }
20
+ interface ChatMessage {
21
+ role: 'system' | 'user' | 'assistant';
22
+ content: string;
23
+ }
24
+ interface ChatProps {
25
+ /** Model to route to (e.g. "gpt-4o", "claude-sonnet-4-5"). */
26
+ model: string;
27
+ /** Cencori API key. Sent as `CENCORI_API_KEY`. Use a publishable/test key on the client. */
28
+ apiKey?: string;
29
+ /**
30
+ * Turn on gateway memory. `{ userId }` is enough — retrieval + writeback
31
+ * default to on. Omit to run a stateless chat.
32
+ */
33
+ memory?: ChatMemoryProp;
34
+ /** System prompt prepended to every request. */
35
+ system?: string;
36
+ /** Seed the transcript (not sent as system — shown as prior turns). */
37
+ initialMessages?: ChatMessage[];
38
+ /** Sampling temperature. */
39
+ temperature?: number;
40
+ /** Max tokens for each reply. */
41
+ maxTokens?: number;
42
+ /** Stream tokens as they arrive. Default: true. */
43
+ stream?: boolean;
44
+ /**
45
+ * Base URL of the Cencori gateway. Defaults to `https://cencori.com`.
46
+ * Override to point at a self-hosted gateway or a same-origin proxy.
47
+ */
48
+ baseUrl?: string;
49
+ /** Placeholder for the input. */
50
+ placeholder?: string;
51
+ /** Called after each reply with how many memories the gateway injected. */
52
+ onMemoryRetrieved?: (count: number) => void;
53
+ /** Called on any request error (before the inline banner renders it). */
54
+ onError?: (error: Error) => void;
55
+ /** Custom empty-state node shown before the first message. */
56
+ emptyState?: ReactNode;
57
+ /** Extra classes on the root element. */
58
+ className?: string;
59
+ /** Hide the "recalled N memories" indicator. Default: shown when memory is on. */
60
+ hideMemoryIndicator?: boolean;
61
+ }
62
+ declare function Chat({ model, apiKey, memory, system, initialMessages, temperature, maxTokens, stream, baseUrl, placeholder, onMemoryRetrieved, onError, emptyState, className, hideMemoryIndicator, }: ChatProps): react_jsx_runtime.JSX.Element;
63
+
64
+ /**
65
+ * useMemory
66
+ *
67
+ * Client hook over the scoped memory API (`/v1/memory/*`) for building custom
68
+ * "what we remember about you" UI — GDPR panels, preference editors, profile
69
+ * pages. Mirrors the roadmap sketch:
70
+ *
71
+ * const { memories, write, forget, search, exportAll } = useMemory({ userId });
72
+ *
73
+ * Reads on mount and after every mutation. Zero external state.
74
+ *
75
+ * Deps: react.
76
+ */
77
+ type MemoryScope = 'session' | 'user';
78
+ interface UseMemoryOptions {
79
+ /** End-user id — scope defaults to `user`. */
80
+ userId?: string;
81
+ /** Session id — pass with `scope: 'session'`. */
82
+ sessionId?: string;
83
+ /** Which scope to read/write. Default: `user`. */
84
+ scope?: MemoryScope;
85
+ /** Optional sub-scope partition (e.g. per-project). */
86
+ namespace?: string;
87
+ /** Cencori API key. Sent as `CENCORI_API_KEY`. */
88
+ apiKey?: string;
89
+ /** Gateway base URL. Default: `https://cencori.com`. */
90
+ baseUrl?: string;
91
+ /** How many memories to list. Default: 50. */
92
+ limit?: number;
93
+ /** Skip the initial list on mount. Default: false. */
94
+ manual?: boolean;
95
+ }
96
+ interface UserMemory {
97
+ id: string;
98
+ content: string;
99
+ namespace?: string | null;
100
+ importance: number;
101
+ createdAt: string | null;
102
+ }
103
+ interface UseMemoryResult {
104
+ /** The user's memories, most recent first. */
105
+ memories: UserMemory[];
106
+ /** True during the initial load or a refresh. */
107
+ loading: boolean;
108
+ /** Last error message, if any. */
109
+ error: string | null;
110
+ /** Re-fetch the list. */
111
+ refresh: () => Promise<void>;
112
+ /** Write a new memory for this user. */
113
+ write: (content: string, opts?: {
114
+ importance?: number;
115
+ metadata?: Record<string, unknown>;
116
+ }) => Promise<void>;
117
+ /** Semantic search over this user's memories (does not mutate the list). */
118
+ search: (query: string, topK?: number) => Promise<UserMemory[]>;
119
+ /** Hard-delete a memory by id. */
120
+ forget: (id: string) => Promise<void>;
121
+ /** Download every memory as a JSON file (client-side GDPR export). */
122
+ exportAll: () => Promise<void>;
123
+ }
124
+ declare function useMemory(options: UseMemoryOptions): UseMemoryResult;
125
+
4
126
  type VisionProvider = 'openai' | 'anthropic' | 'google';
5
127
  interface VisionFormatBannerProps {
6
128
  /** Restrict displayed limits to a specific provider. Omit to show universal (all-provider) limits. */
@@ -49,4 +171,131 @@ interface VisionUploaderProps {
49
171
  }
50
172
  declare function VisionUploader({ endpoint, apiKey, task, provider, model, prompt, onResult, onError, hideBanner, autoCompress, headers, className, }: VisionUploaderProps): react_jsx_runtime.JSX.Element;
51
173
 
52
- export { VisionFormatBanner, type VisionFormatBannerProps, type VisionProvider, type VisionTask, VisionUploader, type VisionUploaderProps };
174
+ /**
175
+ * VoiceRecorder
176
+ *
177
+ * Drop-in microphone recorder + transcriber for the Cencori Voice API. Records
178
+ * from the mic, uploads to the transcriptions endpoint, and returns the text.
179
+ * Zero external state — safe to embed in a customer's own product.
180
+ *
181
+ * Usage:
182
+ * <VoiceRecorder
183
+ * endpoint="https://api.cencori.com/api/ai/audio/transcriptions"
184
+ * apiKey={process.env.NEXT_PUBLIC_CENCORI_KEY}
185
+ * model="nova-3"
186
+ * onTranscript={(text) => console.log(text)}
187
+ * />
188
+ *
189
+ * Deps: react, lucide-react, tailwindcss.
190
+ */
191
+ interface VoiceTranscript {
192
+ text: string;
193
+ language?: string;
194
+ duration?: number;
195
+ provider?: string;
196
+ model?: string;
197
+ segments?: Array<{
198
+ start: number;
199
+ end: number;
200
+ text: string;
201
+ speaker?: string;
202
+ }>;
203
+ }
204
+ interface VoiceRecorderProps {
205
+ /** Transcriptions endpoint. Defaults to same-origin `/api/ai/audio/transcriptions`. */
206
+ endpoint?: string;
207
+ /** Cencori API key. Sent as `Authorization: Bearer`. */
208
+ apiKey?: string;
209
+ /** Transcription model — provider is inferred from it. Default: `whisper-1`. */
210
+ model?: string;
211
+ /** Language hint (e.g. `en`, `yo`, `ha`, `ig`). */
212
+ language?: string;
213
+ /** Request speaker labels (use a diarization-capable model). */
214
+ diarize?: boolean;
215
+ /** Called with the final transcript text. */
216
+ onTranscript?: (text: string, full: VoiceTranscript) => void;
217
+ /** Called on error (before the built-in banner renders it). */
218
+ onError?: (error: {
219
+ code: string;
220
+ message: string;
221
+ }) => void;
222
+ /** Additional request headers to forward (in addition to Authorization). */
223
+ headers?: Record<string, string>;
224
+ /** Extra classes on the root element. */
225
+ className?: string;
226
+ }
227
+ declare function VoiceRecorder({ endpoint, apiKey, model, language, diarize, onTranscript, onError, headers, className, }: VoiceRecorderProps): react_jsx_runtime.JSX.Element;
228
+
229
+ /**
230
+ * SpeakButton
231
+ *
232
+ * Drop-in text-to-speech button for the Cencori Voice API. Synthesizes the
233
+ * given text and plays it back, with loading/playing/error states. Zero
234
+ * external state — safe to embed in a customer's own product.
235
+ *
236
+ * Usage:
237
+ * <SpeakButton
238
+ * endpoint="https://api.cencori.com/api/ai/audio/speech"
239
+ * apiKey={process.env.NEXT_PUBLIC_CENCORI_KEY}
240
+ * text="Hello from Cencori."
241
+ * model="aura-asteria-en"
242
+ * />
243
+ *
244
+ * Deps: react, lucide-react.
245
+ */
246
+ interface SpeakButtonProps {
247
+ /** Text to synthesize. */
248
+ text: string;
249
+ /** Speech endpoint. Defaults to same-origin `/api/ai/audio/speech`. */
250
+ endpoint?: string;
251
+ /** Cencori API key. Sent as `Authorization: Bearer`. */
252
+ apiKey?: string;
253
+ /** TTS model — provider is inferred from it. Default: `tts-1`. */
254
+ model?: string;
255
+ /** Voice id/name. Provider-specific. */
256
+ voice?: string;
257
+ /** Language code (Spitch: `en`, `yo`, `ha`, `ig`, `am`). */
258
+ language?: string;
259
+ /** Button label. Default: "Listen". Pass null to render icon-only. */
260
+ label?: string | null;
261
+ /** Additional request headers to forward (in addition to Authorization). */
262
+ headers?: Record<string, string>;
263
+ onError?: (error: {
264
+ code: string;
265
+ message: string;
266
+ }) => void;
267
+ className?: string;
268
+ }
269
+ declare function SpeakButton({ text, endpoint, apiKey, model, voice, language, label, headers, onError, className, }: SpeakButtonProps): react_jsx_runtime.JSX.Element;
270
+
271
+ /**
272
+ * useVoiceRecorder
273
+ *
274
+ * Minimal microphone-recording hook built on the MediaRecorder API. Handles
275
+ * permission, start/stop, elapsed time, and returns the recorded audio as a
276
+ * Blob. No external state — safe to use inside a customer's own components.
277
+ *
278
+ * Usage:
279
+ * const rec = useVoiceRecorder();
280
+ * rec.start(); // prompts for mic permission
281
+ * const blob = await rec.stop(); // resolves with the recorded audio
282
+ */
283
+ type RecorderState = 'idle' | 'requesting' | 'recording' | 'stopped' | 'error';
284
+ interface UseVoiceRecorderResult {
285
+ state: RecorderState;
286
+ /** Seconds elapsed in the current/last recording. */
287
+ seconds: number;
288
+ /** MediaRecorder mime type in use once recording starts. */
289
+ mimeType: string | null;
290
+ error: string | null;
291
+ /** The most recent recording, available after stop(). */
292
+ blob: Blob | null;
293
+ start: () => Promise<void>;
294
+ /** Stop and resolve with the recorded Blob (also set on `blob`). */
295
+ stop: () => Promise<Blob | null>;
296
+ /** Discard the current recording and reset to idle. */
297
+ reset: () => void;
298
+ }
299
+ declare function useVoiceRecorder(): UseVoiceRecorderResult;
300
+
301
+ export { Chat, type ChatMemoryProp, type ChatMessage, type ChatProps, type MemoryScope, type RecorderState, SpeakButton, type SpeakButtonProps, type UseMemoryOptions, type UseMemoryResult, type UseVoiceRecorderResult, type UserMemory, VisionFormatBanner, type VisionFormatBannerProps, type VisionProvider, type VisionTask, VisionUploader, type VisionUploaderProps, VoiceRecorder, type VoiceRecorderProps, type VoiceTranscript, useMemory, useVoiceRecorder };
@@ -1,6 +1,128 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
+ /** Mirrors `ChatMemoryOptions` from the core SDK. */
5
+ interface ChatMemoryProp {
6
+ userId?: string;
7
+ sessionId?: string;
8
+ scope?: 'session' | 'user';
9
+ retrieve?: boolean;
10
+ write?: boolean;
11
+ topK?: number;
12
+ threshold?: number;
13
+ namespace?: string;
14
+ extract?: {
15
+ model?: string;
16
+ prompt?: string;
17
+ minImportance?: number;
18
+ };
19
+ }
20
+ interface ChatMessage {
21
+ role: 'system' | 'user' | 'assistant';
22
+ content: string;
23
+ }
24
+ interface ChatProps {
25
+ /** Model to route to (e.g. "gpt-4o", "claude-sonnet-4-5"). */
26
+ model: string;
27
+ /** Cencori API key. Sent as `CENCORI_API_KEY`. Use a publishable/test key on the client. */
28
+ apiKey?: string;
29
+ /**
30
+ * Turn on gateway memory. `{ userId }` is enough — retrieval + writeback
31
+ * default to on. Omit to run a stateless chat.
32
+ */
33
+ memory?: ChatMemoryProp;
34
+ /** System prompt prepended to every request. */
35
+ system?: string;
36
+ /** Seed the transcript (not sent as system — shown as prior turns). */
37
+ initialMessages?: ChatMessage[];
38
+ /** Sampling temperature. */
39
+ temperature?: number;
40
+ /** Max tokens for each reply. */
41
+ maxTokens?: number;
42
+ /** Stream tokens as they arrive. Default: true. */
43
+ stream?: boolean;
44
+ /**
45
+ * Base URL of the Cencori gateway. Defaults to `https://cencori.com`.
46
+ * Override to point at a self-hosted gateway or a same-origin proxy.
47
+ */
48
+ baseUrl?: string;
49
+ /** Placeholder for the input. */
50
+ placeholder?: string;
51
+ /** Called after each reply with how many memories the gateway injected. */
52
+ onMemoryRetrieved?: (count: number) => void;
53
+ /** Called on any request error (before the inline banner renders it). */
54
+ onError?: (error: Error) => void;
55
+ /** Custom empty-state node shown before the first message. */
56
+ emptyState?: ReactNode;
57
+ /** Extra classes on the root element. */
58
+ className?: string;
59
+ /** Hide the "recalled N memories" indicator. Default: shown when memory is on. */
60
+ hideMemoryIndicator?: boolean;
61
+ }
62
+ declare function Chat({ model, apiKey, memory, system, initialMessages, temperature, maxTokens, stream, baseUrl, placeholder, onMemoryRetrieved, onError, emptyState, className, hideMemoryIndicator, }: ChatProps): react_jsx_runtime.JSX.Element;
63
+
64
+ /**
65
+ * useMemory
66
+ *
67
+ * Client hook over the scoped memory API (`/v1/memory/*`) for building custom
68
+ * "what we remember about you" UI — GDPR panels, preference editors, profile
69
+ * pages. Mirrors the roadmap sketch:
70
+ *
71
+ * const { memories, write, forget, search, exportAll } = useMemory({ userId });
72
+ *
73
+ * Reads on mount and after every mutation. Zero external state.
74
+ *
75
+ * Deps: react.
76
+ */
77
+ type MemoryScope = 'session' | 'user';
78
+ interface UseMemoryOptions {
79
+ /** End-user id — scope defaults to `user`. */
80
+ userId?: string;
81
+ /** Session id — pass with `scope: 'session'`. */
82
+ sessionId?: string;
83
+ /** Which scope to read/write. Default: `user`. */
84
+ scope?: MemoryScope;
85
+ /** Optional sub-scope partition (e.g. per-project). */
86
+ namespace?: string;
87
+ /** Cencori API key. Sent as `CENCORI_API_KEY`. */
88
+ apiKey?: string;
89
+ /** Gateway base URL. Default: `https://cencori.com`. */
90
+ baseUrl?: string;
91
+ /** How many memories to list. Default: 50. */
92
+ limit?: number;
93
+ /** Skip the initial list on mount. Default: false. */
94
+ manual?: boolean;
95
+ }
96
+ interface UserMemory {
97
+ id: string;
98
+ content: string;
99
+ namespace?: string | null;
100
+ importance: number;
101
+ createdAt: string | null;
102
+ }
103
+ interface UseMemoryResult {
104
+ /** The user's memories, most recent first. */
105
+ memories: UserMemory[];
106
+ /** True during the initial load or a refresh. */
107
+ loading: boolean;
108
+ /** Last error message, if any. */
109
+ error: string | null;
110
+ /** Re-fetch the list. */
111
+ refresh: () => Promise<void>;
112
+ /** Write a new memory for this user. */
113
+ write: (content: string, opts?: {
114
+ importance?: number;
115
+ metadata?: Record<string, unknown>;
116
+ }) => Promise<void>;
117
+ /** Semantic search over this user's memories (does not mutate the list). */
118
+ search: (query: string, topK?: number) => Promise<UserMemory[]>;
119
+ /** Hard-delete a memory by id. */
120
+ forget: (id: string) => Promise<void>;
121
+ /** Download every memory as a JSON file (client-side GDPR export). */
122
+ exportAll: () => Promise<void>;
123
+ }
124
+ declare function useMemory(options: UseMemoryOptions): UseMemoryResult;
125
+
4
126
  type VisionProvider = 'openai' | 'anthropic' | 'google';
5
127
  interface VisionFormatBannerProps {
6
128
  /** Restrict displayed limits to a specific provider. Omit to show universal (all-provider) limits. */
@@ -49,4 +171,131 @@ interface VisionUploaderProps {
49
171
  }
50
172
  declare function VisionUploader({ endpoint, apiKey, task, provider, model, prompt, onResult, onError, hideBanner, autoCompress, headers, className, }: VisionUploaderProps): react_jsx_runtime.JSX.Element;
51
173
 
52
- export { VisionFormatBanner, type VisionFormatBannerProps, type VisionProvider, type VisionTask, VisionUploader, type VisionUploaderProps };
174
+ /**
175
+ * VoiceRecorder
176
+ *
177
+ * Drop-in microphone recorder + transcriber for the Cencori Voice API. Records
178
+ * from the mic, uploads to the transcriptions endpoint, and returns the text.
179
+ * Zero external state — safe to embed in a customer's own product.
180
+ *
181
+ * Usage:
182
+ * <VoiceRecorder
183
+ * endpoint="https://api.cencori.com/api/ai/audio/transcriptions"
184
+ * apiKey={process.env.NEXT_PUBLIC_CENCORI_KEY}
185
+ * model="nova-3"
186
+ * onTranscript={(text) => console.log(text)}
187
+ * />
188
+ *
189
+ * Deps: react, lucide-react, tailwindcss.
190
+ */
191
+ interface VoiceTranscript {
192
+ text: string;
193
+ language?: string;
194
+ duration?: number;
195
+ provider?: string;
196
+ model?: string;
197
+ segments?: Array<{
198
+ start: number;
199
+ end: number;
200
+ text: string;
201
+ speaker?: string;
202
+ }>;
203
+ }
204
+ interface VoiceRecorderProps {
205
+ /** Transcriptions endpoint. Defaults to same-origin `/api/ai/audio/transcriptions`. */
206
+ endpoint?: string;
207
+ /** Cencori API key. Sent as `Authorization: Bearer`. */
208
+ apiKey?: string;
209
+ /** Transcription model — provider is inferred from it. Default: `whisper-1`. */
210
+ model?: string;
211
+ /** Language hint (e.g. `en`, `yo`, `ha`, `ig`). */
212
+ language?: string;
213
+ /** Request speaker labels (use a diarization-capable model). */
214
+ diarize?: boolean;
215
+ /** Called with the final transcript text. */
216
+ onTranscript?: (text: string, full: VoiceTranscript) => void;
217
+ /** Called on error (before the built-in banner renders it). */
218
+ onError?: (error: {
219
+ code: string;
220
+ message: string;
221
+ }) => void;
222
+ /** Additional request headers to forward (in addition to Authorization). */
223
+ headers?: Record<string, string>;
224
+ /** Extra classes on the root element. */
225
+ className?: string;
226
+ }
227
+ declare function VoiceRecorder({ endpoint, apiKey, model, language, diarize, onTranscript, onError, headers, className, }: VoiceRecorderProps): react_jsx_runtime.JSX.Element;
228
+
229
+ /**
230
+ * SpeakButton
231
+ *
232
+ * Drop-in text-to-speech button for the Cencori Voice API. Synthesizes the
233
+ * given text and plays it back, with loading/playing/error states. Zero
234
+ * external state — safe to embed in a customer's own product.
235
+ *
236
+ * Usage:
237
+ * <SpeakButton
238
+ * endpoint="https://api.cencori.com/api/ai/audio/speech"
239
+ * apiKey={process.env.NEXT_PUBLIC_CENCORI_KEY}
240
+ * text="Hello from Cencori."
241
+ * model="aura-asteria-en"
242
+ * />
243
+ *
244
+ * Deps: react, lucide-react.
245
+ */
246
+ interface SpeakButtonProps {
247
+ /** Text to synthesize. */
248
+ text: string;
249
+ /** Speech endpoint. Defaults to same-origin `/api/ai/audio/speech`. */
250
+ endpoint?: string;
251
+ /** Cencori API key. Sent as `Authorization: Bearer`. */
252
+ apiKey?: string;
253
+ /** TTS model — provider is inferred from it. Default: `tts-1`. */
254
+ model?: string;
255
+ /** Voice id/name. Provider-specific. */
256
+ voice?: string;
257
+ /** Language code (Spitch: `en`, `yo`, `ha`, `ig`, `am`). */
258
+ language?: string;
259
+ /** Button label. Default: "Listen". Pass null to render icon-only. */
260
+ label?: string | null;
261
+ /** Additional request headers to forward (in addition to Authorization). */
262
+ headers?: Record<string, string>;
263
+ onError?: (error: {
264
+ code: string;
265
+ message: string;
266
+ }) => void;
267
+ className?: string;
268
+ }
269
+ declare function SpeakButton({ text, endpoint, apiKey, model, voice, language, label, headers, onError, className, }: SpeakButtonProps): react_jsx_runtime.JSX.Element;
270
+
271
+ /**
272
+ * useVoiceRecorder
273
+ *
274
+ * Minimal microphone-recording hook built on the MediaRecorder API. Handles
275
+ * permission, start/stop, elapsed time, and returns the recorded audio as a
276
+ * Blob. No external state — safe to use inside a customer's own components.
277
+ *
278
+ * Usage:
279
+ * const rec = useVoiceRecorder();
280
+ * rec.start(); // prompts for mic permission
281
+ * const blob = await rec.stop(); // resolves with the recorded audio
282
+ */
283
+ type RecorderState = 'idle' | 'requesting' | 'recording' | 'stopped' | 'error';
284
+ interface UseVoiceRecorderResult {
285
+ state: RecorderState;
286
+ /** Seconds elapsed in the current/last recording. */
287
+ seconds: number;
288
+ /** MediaRecorder mime type in use once recording starts. */
289
+ mimeType: string | null;
290
+ error: string | null;
291
+ /** The most recent recording, available after stop(). */
292
+ blob: Blob | null;
293
+ start: () => Promise<void>;
294
+ /** Stop and resolve with the recorded Blob (also set on `blob`). */
295
+ stop: () => Promise<Blob | null>;
296
+ /** Discard the current recording and reset to idle. */
297
+ reset: () => void;
298
+ }
299
+ declare function useVoiceRecorder(): UseVoiceRecorderResult;
300
+
301
+ export { Chat, type ChatMemoryProp, type ChatMessage, type ChatProps, type MemoryScope, type RecorderState, SpeakButton, type SpeakButtonProps, type UseMemoryOptions, type UseMemoryResult, type UseVoiceRecorderResult, type UserMemory, VisionFormatBanner, type VisionFormatBannerProps, type VisionProvider, type VisionTask, VisionUploader, type VisionUploaderProps, VoiceRecorder, type VoiceRecorderProps, type VoiceTranscript, useMemory, useVoiceRecorder };