@eight-atulya/atulya-ai-sdk 0.8.0

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.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Atulya Memory Integration for Vercel AI SDK
2
+
3
+ Give your AI agents persistent, human-like memory using [Atulya](https://github.com/eight-atulya/atulya) with the [Vercel AI SDK](https://ai-sdk.dev).
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install @eight-atulya/atulya-ai-sdk @eight-atulya/atulya-client ai zod
9
+ ```
10
+
11
+ ```typescript
12
+ import { AtulyaClient } from '@eight-atulya/atulya-client';
13
+ import { createAtulyaTools } from '@eight-atulya/atulya-ai-sdk';
14
+ import { generateText } from 'ai';
15
+ import { anthropic } from '@ai-sdk/anthropic';
16
+
17
+ // 1. Initialize Atulya client
18
+ const atulyaClient = new AtulyaClient({
19
+ apiUrl: 'http://localhost:8000',
20
+ });
21
+
22
+ // 2. Create memory tools
23
+ const tools = createAtulyaTools({ client: atulyaClient });
24
+
25
+ // 3. Use with AI SDK
26
+ const result = await generateText({
27
+ model: anthropic('claude-sonnet-4-20250514'),
28
+ tools,
29
+ system: `You have long-term memory. Use:
30
+ - 'recall' to search past conversations
31
+ - 'retain' to remember important information
32
+ - 'reflect' to synthesize insights from memories`,
33
+ prompt: 'Remember that Alice loves hiking and prefers spicy food',
34
+ });
35
+
36
+ console.log(result.text);
37
+ ```
38
+
39
+ ## Features
40
+
41
+ ✅ **Three Memory Tools**: `retain` (store), `recall` (retrieve), and `reflect` (reason over memories)
42
+ ✅ **AI SDK 6 Native**: Works with `generateText`, `streamText`, and `ToolLoopAgent`
43
+ ✅ **Multi-User Support**: Dynamic bank IDs per call for multi-user scenarios
44
+ ✅ **Type-Safe**: Full TypeScript support with Zod schemas
45
+ ✅ **Flexible Client**: Works with the official TypeScript client or custom HTTP clients
46
+
47
+ ## Documentation
48
+
49
+ 📖 **[Full Documentation](https://github.com/eight-atulya/atulya/blob/main/atulya-docs/docs/sdks/integrations/ai-sdk.mdx)**
50
+
51
+ The complete documentation includes:
52
+ - Detailed tool descriptions and parameters
53
+ - Advanced usage patterns (streaming, multi-user, ToolLoopAgent)
54
+ - HTTP client example (no dependencies)
55
+ - TypeScript types and API reference
56
+ - Best practices and system prompt examples
57
+
58
+ ## Running Atulya Locally
59
+
60
+ ```bash
61
+ # Install and run with embedded mode (no setup required)
62
+ uvx atulya-embed@latest -p myapp daemon start
63
+
64
+ # The API will be available at http://localhost:8000
65
+ ```
66
+
67
+ ## Examples
68
+
69
+ Full examples are available in the [GitHub repository](https://github.com/eight-atulya/atulya/tree/main/examples/ai-sdk).
70
+
71
+ ## Support
72
+
73
+ - [Documentation](https://github.com/eight-atulya/atulya/tree/main/atulya-docs)
74
+ - [GitHub Issues](https://github.com/eight-atulya/atulya/issues)
75
+ - Email: support@eightengine.com
76
+
77
+ ## License
78
+
79
+ MIT
@@ -0,0 +1 @@
1
+ export { createAtulyaTools, BudgetSchema, type Budget, type AtulyaClient, type AtulyaTools, type AtulyaToolsOptions, type RecallResult, type RecallResponse, type ReflectFact, type ReflectResponse, type RetainResponse, type EntityState, type ChunkData, } from './tools';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createAtulyaTools, BudgetSchema, } from './tools';
@@ -0,0 +1,270 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Budget levels for recall/reflect operations.
4
+ */
5
+ export declare const BudgetSchema: z.ZodEnum<{
6
+ low: "low";
7
+ mid: "mid";
8
+ high: "high";
9
+ }>;
10
+ export type Budget = z.infer<typeof BudgetSchema>;
11
+ /**
12
+ * Fact types for filtering recall results.
13
+ */
14
+ export declare const FactTypeSchema: z.ZodEnum<{
15
+ world: "world";
16
+ experience: "experience";
17
+ observation: "observation";
18
+ }>;
19
+ export type FactType = z.infer<typeof FactTypeSchema>;
20
+ /**
21
+ * Recall result item from Atulya
22
+ */
23
+ export interface RecallResult {
24
+ id: string;
25
+ text: string;
26
+ type?: string | null;
27
+ entities?: string[] | null;
28
+ context?: string | null;
29
+ occurred_start?: string | null;
30
+ occurred_end?: string | null;
31
+ mentioned_at?: string | null;
32
+ document_id?: string | null;
33
+ metadata?: Record<string, string> | null;
34
+ chunk_id?: string | null;
35
+ }
36
+ /**
37
+ * Entity state with observations
38
+ */
39
+ export interface EntityState {
40
+ entity_id: string;
41
+ canonical_name: string;
42
+ observations: Array<{
43
+ text: string;
44
+ mentioned_at?: string | null;
45
+ }>;
46
+ }
47
+ /**
48
+ * Chunk data
49
+ */
50
+ export interface ChunkData {
51
+ id: string;
52
+ text: string;
53
+ chunk_index: number;
54
+ truncated?: boolean;
55
+ }
56
+ /**
57
+ * Recall response from Atulya
58
+ */
59
+ export interface RecallResponse {
60
+ results: RecallResult[];
61
+ trace?: Record<string, unknown> | null;
62
+ entities?: Record<string, EntityState> | null;
63
+ chunks?: Record<string, ChunkData> | null;
64
+ }
65
+ /**
66
+ * Reflect fact
67
+ */
68
+ export interface ReflectFact {
69
+ id?: string | null;
70
+ text: string;
71
+ type?: string | null;
72
+ context?: string | null;
73
+ occurred_start?: string | null;
74
+ occurred_end?: string | null;
75
+ }
76
+ /**
77
+ * Reflect response from Atulya
78
+ */
79
+ export interface ReflectResponse {
80
+ text: string;
81
+ based_on?: ReflectFact[];
82
+ }
83
+ /**
84
+ * Retain response from Atulya
85
+ */
86
+ export interface RetainResponse {
87
+ success: boolean;
88
+ bank_id: string;
89
+ items_count: number;
90
+ async: boolean;
91
+ }
92
+ /**
93
+ * Mental model trigger configuration
94
+ */
95
+ export interface MentalModelTrigger {
96
+ refresh_after_consolidation?: boolean;
97
+ }
98
+ /**
99
+ * Mental model response from Atulya
100
+ */
101
+ export interface MentalModelResponse {
102
+ mental_model_id: string;
103
+ bank_id: string;
104
+ name?: string;
105
+ content?: string;
106
+ source_query?: string;
107
+ tags?: string[];
108
+ created_at: string;
109
+ updated_at: string;
110
+ trigger?: MentalModelTrigger;
111
+ }
112
+ /**
113
+ * Document response from Atulya
114
+ */
115
+ export interface DocumentResponse {
116
+ id: string;
117
+ bank_id: string;
118
+ original_text: string;
119
+ content_hash: string | null;
120
+ created_at: string;
121
+ updated_at: string;
122
+ memory_unit_count: number;
123
+ tags?: string[];
124
+ }
125
+ /**
126
+ * Atulya client interface - matches @eight-atulya/atulya-client
127
+ */
128
+ export interface AtulyaClient {
129
+ retain(bankId: string, content: string, options?: {
130
+ timestamp?: Date | string;
131
+ context?: string;
132
+ metadata?: Record<string, string>;
133
+ documentId?: string;
134
+ tags?: string[];
135
+ async?: boolean;
136
+ }): Promise<RetainResponse>;
137
+ recall(bankId: string, query: string, options?: {
138
+ types?: FactType[];
139
+ maxTokens?: number;
140
+ budget?: Budget;
141
+ trace?: boolean;
142
+ queryTimestamp?: string;
143
+ includeEntities?: boolean;
144
+ maxEntityTokens?: number;
145
+ includeChunks?: boolean;
146
+ maxChunkTokens?: number;
147
+ }): Promise<RecallResponse>;
148
+ reflect(bankId: string, query: string, options?: {
149
+ context?: string;
150
+ budget?: Budget;
151
+ maxTokens?: number;
152
+ }): Promise<ReflectResponse>;
153
+ getMentalModel(bankId: string, mentalModelId: string): Promise<MentalModelResponse>;
154
+ getDocument(bankId: string, documentId: string): Promise<DocumentResponse | null>;
155
+ }
156
+ export interface AtulyaToolsOptions {
157
+ /** Atulya client instance */
158
+ client: AtulyaClient;
159
+ /** Memory bank ID to use for all tool calls (e.g. the user ID) */
160
+ bankId: string;
161
+ /** Options for the retain tool */
162
+ retain?: {
163
+ /** Fire-and-forget retain without waiting for completion (default: false) */
164
+ async?: boolean;
165
+ /** Tags always attached to every retained memory (default: undefined) */
166
+ tags?: string[];
167
+ /** Metadata always attached to every retained memory (default: undefined) */
168
+ metadata?: Record<string, string>;
169
+ /** Custom tool description */
170
+ description?: string;
171
+ };
172
+ /** Options for the recall tool */
173
+ recall?: {
174
+ /** Restrict results to these fact types: 'world', 'experience', 'observation' (default: undefined = all types) */
175
+ types?: FactType[];
176
+ /** Maximum tokens to return (default: undefined = API default) */
177
+ maxTokens?: number;
178
+ /** Processing budget controlling latency vs. depth (default: 'mid') */
179
+ budget?: Budget;
180
+ /** Include entity observations in results (default: false) */
181
+ includeEntities?: boolean;
182
+ /** Include raw source chunks in results (default: false) */
183
+ includeChunks?: boolean;
184
+ /** Custom tool description */
185
+ description?: string;
186
+ };
187
+ /** Options for the reflect tool */
188
+ reflect?: {
189
+ /** Processing budget controlling latency vs. depth (default: 'mid') */
190
+ budget?: Budget;
191
+ /** Maximum tokens for the response (default: undefined = API default) */
192
+ maxTokens?: number;
193
+ /** Custom tool description */
194
+ description?: string;
195
+ };
196
+ /** Options for the getMentalModel tool */
197
+ getMentalModel?: {
198
+ /** Custom tool description */
199
+ description?: string;
200
+ };
201
+ /** Options for the getDocument tool */
202
+ getDocument?: {
203
+ /** Custom tool description */
204
+ description?: string;
205
+ };
206
+ }
207
+ /**
208
+ * Creates AI SDK tools for Atulya memory operations.
209
+ *
210
+ * The bank ID and all infrastructure concerns (budget, tags, async mode, etc.)
211
+ * are fixed at creation time. The agent only controls semantic inputs:
212
+ * content, queries, names, and timestamps.
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * const tools = createAtulyaTools({
217
+ * client: atulyaClient,
218
+ * bankId: userId,
219
+ * recall: { budget: 'high', includeEntities: true },
220
+ * retain: { async: true, tags: ['env:prod'] },
221
+ * });
222
+ *
223
+ * const result = await generateText({
224
+ * model: openai('gpt-4o'),
225
+ * tools,
226
+ * messages,
227
+ * });
228
+ * ```
229
+ */
230
+ export declare function createAtulyaTools({ client, bankId, retain: retainOpts, recall: recallOpts, reflect: reflectOpts, getMentalModel: getMentalModelOpts, getDocument: getDocumentOpts, }: AtulyaToolsOptions): {
231
+ retain: import("ai").Tool<{
232
+ content: string;
233
+ documentId?: string | undefined;
234
+ timestamp?: string | undefined;
235
+ context?: string | undefined;
236
+ }, {
237
+ success: boolean;
238
+ itemsCount: number;
239
+ }>;
240
+ recall: import("ai").Tool<{
241
+ query: string;
242
+ queryTimestamp?: string | undefined;
243
+ }, {
244
+ results: RecallResult[];
245
+ entities?: Record<string, EntityState> | null;
246
+ }>;
247
+ reflect: import("ai").Tool<{
248
+ query: string;
249
+ context?: string | undefined;
250
+ }, {
251
+ text: string;
252
+ basedOn?: ReflectFact[];
253
+ }>;
254
+ getMentalModel: import("ai").Tool<{
255
+ mentalModelId: string;
256
+ }, {
257
+ content: string;
258
+ name?: string;
259
+ updatedAt: string;
260
+ }>;
261
+ getDocument: import("ai").Tool<{
262
+ documentId: string;
263
+ }, {
264
+ originalText: string;
265
+ id: string;
266
+ createdAt: string;
267
+ updatedAt: string;
268
+ } | null>;
269
+ };
270
+ export type AtulyaTools = ReturnType<typeof createAtulyaTools>;
@@ -0,0 +1,146 @@
1
+ import { tool } from 'ai';
2
+ import { z } from 'zod';
3
+ /**
4
+ * Budget levels for recall/reflect operations.
5
+ */
6
+ export const BudgetSchema = z.enum(['low', 'mid', 'high']);
7
+ /**
8
+ * Fact types for filtering recall results.
9
+ */
10
+ export const FactTypeSchema = z.enum(['world', 'experience', 'observation']);
11
+ /**
12
+ * Creates AI SDK tools for Atulya memory operations.
13
+ *
14
+ * The bank ID and all infrastructure concerns (budget, tags, async mode, etc.)
15
+ * are fixed at creation time. The agent only controls semantic inputs:
16
+ * content, queries, names, and timestamps.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const tools = createAtulyaTools({
21
+ * client: atulyaClient,
22
+ * bankId: userId,
23
+ * recall: { budget: 'high', includeEntities: true },
24
+ * retain: { async: true, tags: ['env:prod'] },
25
+ * });
26
+ *
27
+ * const result = await generateText({
28
+ * model: openai('gpt-4o'),
29
+ * tools,
30
+ * messages,
31
+ * });
32
+ * ```
33
+ */
34
+ export function createAtulyaTools({ client, bankId, retain: retainOpts = {}, recall: recallOpts = {}, reflect: reflectOpts = {}, getMentalModel: getMentalModelOpts = {}, getDocument: getDocumentOpts = {}, }) {
35
+ // Agent-controlled params only: content, timestamp, documentId, context
36
+ const retainParams = z.object({
37
+ content: z.string().describe('Content to store in memory'),
38
+ documentId: z.string().optional().describe('Optional document ID for grouping/upserting content'),
39
+ timestamp: z.string().optional().describe('Optional ISO timestamp for when the memory occurred'),
40
+ context: z.string().optional().describe('Optional context about the memory'),
41
+ });
42
+ // Agent-controlled params only: query, queryTimestamp
43
+ const recallParams = z.object({
44
+ query: z.string().describe('What to search for in memory'),
45
+ queryTimestamp: z.string().optional().describe('Query from a specific point in time (ISO format)'),
46
+ });
47
+ // Agent-controlled params only: query, context
48
+ const reflectParams = z.object({
49
+ query: z.string().describe('Question to reflect on based on memories'),
50
+ context: z.string().optional().describe('Additional context for the reflection'),
51
+ });
52
+ const getMentalModelParams = z.object({
53
+ mentalModelId: z.string().describe('ID of the mental model to retrieve'),
54
+ });
55
+ const getDocumentParams = z.object({
56
+ documentId: z.string().describe('ID of the document to retrieve'),
57
+ });
58
+ return {
59
+ retain: tool({
60
+ description: retainOpts.description ??
61
+ `Store information in long-term memory. Use this when information should be remembered for future interactions, such as user preferences, facts, experiences, or important context.`,
62
+ inputSchema: retainParams,
63
+ execute: async (input) => {
64
+ console.log('[AI SDK Tool] Retain input:', {
65
+ bankId,
66
+ documentId: input.documentId,
67
+ hasContent: !!input.content,
68
+ });
69
+ const result = await client.retain(bankId, input.content, {
70
+ documentId: input.documentId,
71
+ timestamp: input.timestamp,
72
+ context: input.context,
73
+ tags: retainOpts.tags,
74
+ metadata: retainOpts.metadata,
75
+ async: retainOpts.async ?? false,
76
+ });
77
+ return { success: result.success, itemsCount: result.items_count };
78
+ },
79
+ }),
80
+ recall: tool({
81
+ description: recallOpts.description ??
82
+ `Search memory for relevant information. Use this to find previously stored information that can help personalize responses or provide context.`,
83
+ inputSchema: recallParams,
84
+ execute: async (input) => {
85
+ const result = await client.recall(bankId, input.query, {
86
+ types: recallOpts.types,
87
+ maxTokens: recallOpts.maxTokens,
88
+ budget: recallOpts.budget ?? 'mid',
89
+ queryTimestamp: input.queryTimestamp,
90
+ includeEntities: recallOpts.includeEntities ?? false,
91
+ includeChunks: recallOpts.includeChunks ?? false,
92
+ });
93
+ return {
94
+ results: result.results ?? [],
95
+ entities: result.entities,
96
+ };
97
+ },
98
+ }),
99
+ reflect: tool({
100
+ description: reflectOpts.description ??
101
+ `Analyze memories to form insights and generate contextual answers. Use this to understand patterns, synthesize information, or answer questions that require reasoning over stored memories.`,
102
+ inputSchema: reflectParams,
103
+ execute: async (input) => {
104
+ const result = await client.reflect(bankId, input.query, {
105
+ context: input.context,
106
+ budget: reflectOpts.budget ?? 'mid',
107
+ maxTokens: reflectOpts.maxTokens,
108
+ });
109
+ return {
110
+ text: result.text ?? 'No insights available yet.',
111
+ basedOn: result.based_on,
112
+ };
113
+ },
114
+ }),
115
+ getMentalModel: tool({
116
+ description: getMentalModelOpts.description ??
117
+ `Retrieve a mental model to get consolidated knowledge synthesized from memories. Mental models provide synthesized insights that are faster and more efficient to retrieve than searching through raw memories.`,
118
+ inputSchema: getMentalModelParams,
119
+ execute: async (input) => {
120
+ const result = await client.getMentalModel(bankId, input.mentalModelId);
121
+ return {
122
+ content: result.content ?? 'No content available yet.',
123
+ name: result.name,
124
+ updatedAt: result.updated_at,
125
+ };
126
+ },
127
+ }),
128
+ getDocument: tool({
129
+ description: getDocumentOpts.description ??
130
+ `Retrieve a stored document by its ID. Documents are used to store structured data like application state, user profiles, or any data that needs exact retrieval.`,
131
+ inputSchema: getDocumentParams,
132
+ execute: async (input) => {
133
+ const result = await client.getDocument(bankId, input.documentId);
134
+ if (!result) {
135
+ return null;
136
+ }
137
+ return {
138
+ originalText: result.original_text,
139
+ id: result.id,
140
+ createdAt: result.created_at,
141
+ updatedAt: result.updated_at,
142
+ };
143
+ },
144
+ }),
145
+ };
146
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@eight-atulya/atulya-ai-sdk",
3
+ "version": "0.8.0",
4
+ "description": "Atulya memory integration for Vercel AI SDK - Give your AI agents persistent, human-like memory",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "keywords": [
15
+ "ai",
16
+ "ai-sdk",
17
+ "vercel",
18
+ "memory",
19
+ "atulya",
20
+ "agents",
21
+ "llm",
22
+ "long-term-memory"
23
+ ],
24
+ "author": "Anurag Atulya <support@eightengine.com>",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/eight-atulya/atulya.git",
29
+ "directory": "atulya-integrations/ai-sdk"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "dev": "tsc --watch",
38
+ "clean": "rm -rf dist",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "prepublishOnly": "npm run clean && npm run build"
42
+ },
43
+ "peerDependencies": {
44
+ "ai": "^6.0.0",
45
+ "zod": "^3.0.0 || ^4.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.0.0",
49
+ "@vitest/ui": "^4.0.18",
50
+ "ai": "^6.0.2",
51
+ "typescript": "^5.7.0",
52
+ "vitest": "^4.0.18",
53
+ "zod": "^4.2.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=22"
57
+ },
58
+ "overrides": {
59
+ "rollup": "^4.59.0"
60
+ }
61
+ }