@cortexmemory/cli 0.26.0 → 0.27.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.
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +2 -18
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +153 -17
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +373 -70
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +102 -46
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +94 -7
- package/dist/commands/status.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +23 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +20 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/init/convex-setup.d.ts +58 -6
- package/dist/utils/init/convex-setup.d.ts.map +1 -1
- package/dist/utils/init/convex-setup.js +261 -57
- package/dist/utils/init/convex-setup.js.map +1 -1
- package/dist/utils/init/env-generator.d.ts.map +1 -1
- package/dist/utils/init/env-generator.js +12 -2
- package/dist/utils/init/env-generator.js.map +1 -1
- package/dist/utils/init/graph-setup.d.ts.map +1 -1
- package/dist/utils/init/graph-setup.js +12 -0
- package/dist/utils/init/graph-setup.js.map +1 -1
- package/dist/utils/init/quickstart-setup.d.ts +87 -0
- package/dist/utils/init/quickstart-setup.d.ts.map +1 -0
- package/dist/utils/init/quickstart-setup.js +462 -0
- package/dist/utils/init/quickstart-setup.js.map +1 -0
- package/dist/utils/init/types.d.ts +4 -0
- package/dist/utils/init/types.d.ts.map +1 -1
- package/dist/utils/schema-sync.d.ts.map +1 -1
- package/dist/utils/schema-sync.js +27 -21
- package/dist/utils/schema-sync.js.map +1 -1
- package/package.json +3 -2
- package/templates/vercel-ai-quickstart/.env.local.example +45 -0
- package/templates/vercel-ai-quickstart/README.md +280 -0
- package/templates/vercel-ai-quickstart/app/api/chat/route.ts +196 -0
- package/templates/vercel-ai-quickstart/app/api/facts/route.ts +39 -0
- package/templates/vercel-ai-quickstart/app/api/health/route.ts +99 -0
- package/templates/vercel-ai-quickstart/app/api/memories/route.ts +37 -0
- package/templates/vercel-ai-quickstart/app/globals.css +114 -0
- package/templates/vercel-ai-quickstart/app/layout.tsx +19 -0
- package/templates/vercel-ai-quickstart/app/page.tsx +131 -0
- package/templates/vercel-ai-quickstart/components/ChatInterface.tsx +237 -0
- package/templates/vercel-ai-quickstart/components/ConvexClientProvider.tsx +21 -0
- package/templates/vercel-ai-quickstart/components/DataPreview.tsx +57 -0
- package/templates/vercel-ai-quickstart/components/HealthStatus.tsx +214 -0
- package/templates/vercel-ai-quickstart/components/LayerCard.tsx +263 -0
- package/templates/vercel-ai-quickstart/components/LayerFlowDiagram.tsx +195 -0
- package/templates/vercel-ai-quickstart/components/MemorySpaceSwitcher.tsx +93 -0
- package/templates/vercel-ai-quickstart/convex/conversations.ts +67 -0
- package/templates/vercel-ai-quickstart/convex/facts.ts +131 -0
- package/templates/vercel-ai-quickstart/convex/health.ts +15 -0
- package/templates/vercel-ai-quickstart/convex/memories.ts +104 -0
- package/templates/vercel-ai-quickstart/convex/schema.ts +20 -0
- package/templates/vercel-ai-quickstart/convex/users.ts +105 -0
- package/templates/vercel-ai-quickstart/lib/animations.ts +146 -0
- package/templates/vercel-ai-quickstart/lib/layer-tracking.ts +214 -0
- package/templates/vercel-ai-quickstart/next.config.js +7 -0
- package/templates/vercel-ai-quickstart/package.json +41 -0
- package/templates/vercel-ai-quickstart/postcss.config.js +5 -0
- package/templates/vercel-ai-quickstart/tailwind.config.js +37 -0
- package/templates/vercel-ai-quickstart/tsconfig.json +33 -0
|
@@ -12,32 +12,32 @@
|
|
|
12
12
|
* This will use the schema files from that directory's convex-dev folder instead
|
|
13
13
|
* of the installed @cortexmemory/sdk package.
|
|
14
14
|
*/
|
|
15
|
-
import { existsSync, readFileSync } from "fs";
|
|
15
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
16
16
|
import { copyFile, mkdir } from "fs/promises";
|
|
17
17
|
import { createHash } from "crypto";
|
|
18
18
|
import { join, dirname } from "path";
|
|
19
19
|
import pc from "picocolors";
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* Discover all syncable files from the SDK's convex-dev folder
|
|
22
|
+
* Includes all .ts files and tsconfig.json, excludes _generated/ directory
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
function discoverSchemaFiles(sdkConvexPath) {
|
|
25
|
+
try {
|
|
26
|
+
const entries = readdirSync(sdkConvexPath, { withFileTypes: true });
|
|
27
|
+
return entries
|
|
28
|
+
.filter((entry) => {
|
|
29
|
+
// Skip directories (like _generated/)
|
|
30
|
+
if (entry.isDirectory())
|
|
31
|
+
return false;
|
|
32
|
+
// Include .ts files and tsconfig.json
|
|
33
|
+
return entry.name.endsWith(".ts") || entry.name === "tsconfig.json";
|
|
34
|
+
})
|
|
35
|
+
.map((entry) => entry.name);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
41
|
/**
|
|
42
42
|
* Find the @cortexmemory/sdk package
|
|
43
43
|
*
|
|
@@ -132,6 +132,12 @@ export async function syncConvexSchema(projectPath, options) {
|
|
|
132
132
|
}
|
|
133
133
|
result.sdkConvexPath = sdkConvexPath;
|
|
134
134
|
result.sdkVersion = getSdkVersion(sdkPath);
|
|
135
|
+
// Discover all syncable files from SDK
|
|
136
|
+
const schemaFiles = discoverSchemaFiles(sdkConvexPath);
|
|
137
|
+
if (schemaFiles.length === 0) {
|
|
138
|
+
result.error = `No schema files found in ${sdkConvexPath}`;
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
135
141
|
// Ensure project's convex folder exists
|
|
136
142
|
if (!existsSync(result.projectConvexPath)) {
|
|
137
143
|
if (!options?.dryRun) {
|
|
@@ -139,7 +145,7 @@ export async function syncConvexSchema(projectPath, options) {
|
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
147
|
// Compare and sync each file
|
|
142
|
-
for (const fileName of
|
|
148
|
+
for (const fileName of schemaFiles) {
|
|
143
149
|
const sdkFilePath = join(sdkConvexPath, fileName);
|
|
144
150
|
const projectFilePath = join(result.projectConvexPath, fileName);
|
|
145
151
|
// Skip if SDK doesn't have this file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-sync.js","sourceRoot":"","sources":["../../src/utils/schema-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"schema-sync.js","sourceRoot":"","sources":["../../src/utils/schema-sync.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexmemory/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"description": "CLI tool for managing Cortex Memory deployments, performing administrative tasks, and streamlining development workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"README.md"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"
|
|
17
|
+
"prebuild": "node scripts/sync-quickstart-template.js",
|
|
18
|
+
"build": "npm run prebuild && tsc && chmod +x dist/index.js",
|
|
18
19
|
"dev": "tsc --watch",
|
|
19
20
|
"lint": "eslint . --report-unused-disable-directives",
|
|
20
21
|
"test": "node --experimental-vm-modules $(npm root)/.bin/jest",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2
|
+
# Required Configuration
|
|
3
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
4
|
+
|
|
5
|
+
# Your Convex deployment URL
|
|
6
|
+
# Get this from: https://dashboard.convex.dev
|
|
7
|
+
CONVEX_URL=https://your-project.convex.cloud
|
|
8
|
+
|
|
9
|
+
# OpenAI API Key for LLM and embeddings
|
|
10
|
+
# Get this from: https://platform.openai.com/api-keys
|
|
11
|
+
OPENAI_API_KEY=sk-...
|
|
12
|
+
|
|
13
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
14
|
+
# Memory Space Configuration
|
|
15
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
|
|
17
|
+
# Default memory space for the demo
|
|
18
|
+
MEMORY_SPACE_ID=quickstart-demo
|
|
19
|
+
|
|
20
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
21
|
+
# Optional: Fact Extraction (SDK v0.18.0+)
|
|
22
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
23
|
+
|
|
24
|
+
# Enable automatic LLM-powered fact extraction
|
|
25
|
+
CORTEX_FACT_EXTRACTION=true
|
|
26
|
+
|
|
27
|
+
# Model for fact extraction (default: gpt-4o-mini)
|
|
28
|
+
CORTEX_FACT_EXTRACTION_MODEL=gpt-4o-mini
|
|
29
|
+
|
|
30
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
31
|
+
# Optional: Graph Database (SDK v0.19.0+)
|
|
32
|
+
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
33
|
+
|
|
34
|
+
# Enable automatic graph sync
|
|
35
|
+
# CORTEX_GRAPH_SYNC=true
|
|
36
|
+
|
|
37
|
+
# Neo4j connection (choose one)
|
|
38
|
+
# NEO4J_URI=bolt://localhost:7687
|
|
39
|
+
# NEO4J_USERNAME=neo4j
|
|
40
|
+
# NEO4J_PASSWORD=your-password
|
|
41
|
+
|
|
42
|
+
# Or Memgraph connection
|
|
43
|
+
# MEMGRAPH_URI=bolt://localhost:7687
|
|
44
|
+
# MEMGRAPH_USERNAME=
|
|
45
|
+
# MEMGRAPH_PASSWORD=
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Cortex Memory + Vercel AI SDK Quickstart
|
|
2
|
+
|
|
3
|
+
This is the official quickstart demo for **Cortex Memory** with the **Vercel AI SDK**. It provides an interactive visualization of how data flows through the Cortex memory orchestration system in real-time.
|
|
4
|
+
|
|
5
|
+
> **SDK v0.24.0**: Now with **Belief Revision**! When users change their preferences (e.g., "I now prefer purple" after saying "I like blue"), Cortex intelligently updates or supersedes existing facts instead of creating duplicates.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🧠 **Real-time Memory Visualization** - Watch data flow through all Cortex layers (Memory Space → User → Agent → Conversation → Vector → Facts → Graph)
|
|
10
|
+
- 💬 **Interactive Chat** - Send messages and see them processed with automatic memory storage
|
|
11
|
+
- 📊 **Layer Flow Diagram** - Animated visualization showing latency and data at each layer
|
|
12
|
+
- 🔀 **Memory Space Switching** - Demonstrate multi-tenant isolation by switching between memory spaces
|
|
13
|
+
- ⚡ **Streaming Support** - Full streaming with progressive fact extraction
|
|
14
|
+
- 🧹 **Belief Revision** - Intelligent fact updates when information changes (v0.24.0)
|
|
15
|
+
- 🔄 **Smart Fact Deduplication** - Semantic matching prevents duplicate facts across sessions (v0.22.0)
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- Node.js 18+
|
|
20
|
+
- A Convex deployment ([get started](https://www.convex.dev/))
|
|
21
|
+
- An OpenAI API key ([get one](https://platform.openai.com/api-keys))
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Local Development (within monorepo)
|
|
26
|
+
|
|
27
|
+
1. **Install dependencies**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd packages/vercel-ai-provider/quickstart
|
|
31
|
+
npm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> **Note**: The `package.json` uses `file:` references to link to the local SDK and provider packages. This allows you to test changes to the provider immediately.
|
|
35
|
+
|
|
36
|
+
### Using Published Packages
|
|
37
|
+
|
|
38
|
+
If you want to use the published npm packages instead, update `package.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@cortexmemory/sdk": "^0.24.0",
|
|
44
|
+
"@cortexmemory/vercel-ai-provider": "^1.0.0"
|
|
45
|
+
// ... other deps
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
2. **Set up environment variables**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cp .env.local.example .env.local
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Edit `.env.local` and add your credentials:
|
|
57
|
+
|
|
58
|
+
```env
|
|
59
|
+
CONVEX_URL=https://your-project.convex.cloud
|
|
60
|
+
NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
|
|
61
|
+
OPENAI_API_KEY=sk-...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. **Deploy Convex schema**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run convex:dev
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
4. **Start the development server**
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run dev
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
5. **Open the demo**
|
|
77
|
+
|
|
78
|
+
Visit [http://localhost:3000](http://localhost:3000) to see the demo in action.
|
|
79
|
+
|
|
80
|
+
## What This Demo Shows
|
|
81
|
+
|
|
82
|
+
### Memory Layer Orchestration
|
|
83
|
+
|
|
84
|
+
When you send a message, you'll see it flow through these layers:
|
|
85
|
+
|
|
86
|
+
| Layer | Description |
|
|
87
|
+
| ---------------- | ----------------------------------------------- |
|
|
88
|
+
| **Memory Space** | Isolated namespace for multi-tenancy |
|
|
89
|
+
| **User** | User profile and identity |
|
|
90
|
+
| **Agent** | AI agent participant (required in SDK v0.17.0+) |
|
|
91
|
+
| **Conversation** | Message storage with threading |
|
|
92
|
+
| **Vector** | Semantic embeddings for similarity search |
|
|
93
|
+
| **Facts** | Extracted structured information |
|
|
94
|
+
| **Graph** | Entity relationships (optional) |
|
|
95
|
+
|
|
96
|
+
### Key Features Demonstrated
|
|
97
|
+
|
|
98
|
+
1. **Belief Revision** - SDK v0.24.0 intelligently updates/supersedes facts when information changes
|
|
99
|
+
2. **Unified Retrieval (recall)** - SDK v0.23.0 retrieves from vector + facts + graph in one call
|
|
100
|
+
3. **agentId Requirement** - SDK v0.17.0+ requires `agentId` for all user-agent conversations
|
|
101
|
+
4. **Automatic Fact Extraction** - LLM-powered extraction of preferences, identity, relationships
|
|
102
|
+
5. **Semantic Fact Deduplication** - SDK v0.22.0 automatically prevents duplicate facts using embedding similarity
|
|
103
|
+
6. **Multi-tenant Isolation** - Switch memory spaces to see complete isolation
|
|
104
|
+
7. **Streaming with Memory** - Full streaming support with progressive storage
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
The chat API route at `/app/api/chat/route.ts` shows how to configure the Cortex Memory provider:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { createCortexMemory } from "@cortexmemory/vercel-ai-provider";
|
|
112
|
+
import { openai, createOpenAI } from "@ai-sdk/openai";
|
|
113
|
+
import { streamText, embed } from "ai";
|
|
114
|
+
|
|
115
|
+
const openaiClient = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
116
|
+
|
|
117
|
+
const cortexMemory = createCortexMemory({
|
|
118
|
+
convexUrl: process.env.CONVEX_URL!,
|
|
119
|
+
memorySpaceId: "quickstart-demo",
|
|
120
|
+
|
|
121
|
+
// User identification
|
|
122
|
+
userId: "demo-user",
|
|
123
|
+
userName: "Demo User",
|
|
124
|
+
|
|
125
|
+
// Agent identification (REQUIRED in SDK v0.17.0+)
|
|
126
|
+
agentId: "quickstart-assistant",
|
|
127
|
+
agentName: "Cortex Demo Assistant",
|
|
128
|
+
|
|
129
|
+
// Optional features
|
|
130
|
+
enableGraphMemory: process.env.CORTEX_GRAPH_SYNC === "true",
|
|
131
|
+
enableFactExtraction: process.env.CORTEX_FACT_EXTRACTION === "true",
|
|
132
|
+
|
|
133
|
+
// Belief Revision (v0.24.0+)
|
|
134
|
+
// Automatically handles fact updates when user changes their mind
|
|
135
|
+
// e.g., "I like blue" → "I prefer purple" will UPDATE/SUPERSEDE the old fact
|
|
136
|
+
beliefRevision: {
|
|
137
|
+
enabled: true,
|
|
138
|
+
slotMatching: true, // Fast slot-based conflict detection
|
|
139
|
+
llmResolution: true, // LLM-based resolution for nuanced conflicts
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
// Embedding provider (required for semantic matching)
|
|
143
|
+
embeddingProvider: {
|
|
144
|
+
generate: async (text) => {
|
|
145
|
+
const result = await embed({
|
|
146
|
+
model: openaiClient.embedding("text-embedding-3-small"),
|
|
147
|
+
value: text,
|
|
148
|
+
});
|
|
149
|
+
return result.embedding;
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const result = await streamText({
|
|
155
|
+
model: cortexMemory(openai("gpt-4o-mini")),
|
|
156
|
+
messages,
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Architecture
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
quickstart/
|
|
164
|
+
├── app/
|
|
165
|
+
│ ├── api/
|
|
166
|
+
│ │ ├── chat/route.ts # Main chat endpoint with Cortex
|
|
167
|
+
│ │ ├── memories/route.ts # Memory inspection endpoint
|
|
168
|
+
│ │ └── facts/route.ts # Facts inspection endpoint
|
|
169
|
+
│ ├── layout.tsx
|
|
170
|
+
│ ├── page.tsx # Main demo page
|
|
171
|
+
│ └── globals.css
|
|
172
|
+
├── components/
|
|
173
|
+
│ ├── ChatInterface.tsx # Chat UI component
|
|
174
|
+
│ ├── LayerFlowDiagram.tsx # Hero visualization component
|
|
175
|
+
│ ├── LayerCard.tsx # Individual layer status card
|
|
176
|
+
│ ├── DataPreview.tsx # Expandable data viewer
|
|
177
|
+
│ └── MemorySpaceSwitcher.tsx
|
|
178
|
+
├── lib/
|
|
179
|
+
│ ├── layer-tracking.ts # Layer status management
|
|
180
|
+
│ └── animations.ts # Framer Motion variants
|
|
181
|
+
└── convex/
|
|
182
|
+
├── schema.ts # Convex schema
|
|
183
|
+
├── conversations.ts # Conversation queries
|
|
184
|
+
├── memories.ts # Memory queries
|
|
185
|
+
├── facts.ts # Facts queries
|
|
186
|
+
└── users.ts # User queries
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Learn More
|
|
190
|
+
|
|
191
|
+
- [Cortex Memory Documentation](https://cortexmemory.dev/docs)
|
|
192
|
+
- [Vercel AI SDK Documentation](https://sdk.vercel.ai/docs)
|
|
193
|
+
- [API Reference](/Documentation/03-api-reference/02-memory-operations.md)
|
|
194
|
+
|
|
195
|
+
## Troubleshooting
|
|
196
|
+
|
|
197
|
+
### "agentId is required"
|
|
198
|
+
|
|
199
|
+
Since SDK v0.17.0, all user-agent conversations require an `agentId`. Add it to your configuration:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const cortexMemory = createCortexMemory({
|
|
203
|
+
// ... other config
|
|
204
|
+
agentId: "my-assistant", // Required!
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Memories not appearing
|
|
209
|
+
|
|
210
|
+
1. Check that your Convex deployment is running
|
|
211
|
+
2. Verify `CONVEX_URL` is set correctly
|
|
212
|
+
3. Ensure the memory space ID matches between frontend and backend
|
|
213
|
+
|
|
214
|
+
### Fact extraction not working
|
|
215
|
+
|
|
216
|
+
Enable fact extraction via environment variable:
|
|
217
|
+
|
|
218
|
+
```env
|
|
219
|
+
CORTEX_FACT_EXTRACTION=true
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Duplicate facts being created
|
|
223
|
+
|
|
224
|
+
Ensure you have `embeddingProvider` configured for optimal semantic deduplication:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const cortexMemory = createCortexMemory({
|
|
228
|
+
// ... other config
|
|
229
|
+
embeddingProvider: {
|
|
230
|
+
generate: async (text) => {
|
|
231
|
+
const result = await embed({
|
|
232
|
+
model: openaiClient.embedding("text-embedding-3-small"),
|
|
233
|
+
value: text,
|
|
234
|
+
});
|
|
235
|
+
return result.embedding;
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Without `embeddingProvider`, deduplication falls back to `structural` matching (subject + predicate + object), which is less accurate for semantically similar facts.
|
|
242
|
+
|
|
243
|
+
To disable deduplication entirely (not recommended):
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const cortexMemory = createCortexMemory({
|
|
247
|
+
// ... other config
|
|
248
|
+
factDeduplication: false, // Uses pre-v0.22.0 behavior
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Facts not being updated when user changes preferences
|
|
253
|
+
|
|
254
|
+
If you say "I like blue" then later say "I prefer purple" and both facts remain, enable **Belief Revision** (v0.24.0+):
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const cortexMemory = createCortexMemory({
|
|
258
|
+
// ... other config
|
|
259
|
+
beliefRevision: {
|
|
260
|
+
enabled: true,
|
|
261
|
+
slotMatching: true, // Fast detection via subject-predicate matching
|
|
262
|
+
llmResolution: true, // LLM resolves nuanced conflicts
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Revision actions explained:**
|
|
268
|
+
|
|
269
|
+
| Action | Description | Example |
|
|
270
|
+
| ----------- | -------------------------------------------------- | ------------------------------------- |
|
|
271
|
+
| `CREATE` | New fact with no conflicts | First time mentioning favorite color |
|
|
272
|
+
| `UPDATE` | Existing fact refined with new details | "I like blue" → "I love dark blue" |
|
|
273
|
+
| `SUPERSEDE` | Old fact replaced by contradicting new information | "I like blue" → "I prefer purple now" |
|
|
274
|
+
| `NONE` | Duplicate or irrelevant, no storage needed | Saying "I like blue" twice |
|
|
275
|
+
|
|
276
|
+
The demo visualization shows these actions with colored badges on the Facts layer.
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
FSL-1.1-Apache-2.0 - See LICENSE.md in the root of the repository.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { createCortexMemoryAsync } from "@cortexmemory/vercel-ai-provider";
|
|
2
|
+
import type {
|
|
3
|
+
LayerObserver,
|
|
4
|
+
CortexMemoryConfig,
|
|
5
|
+
} from "@cortexmemory/vercel-ai-provider";
|
|
6
|
+
import { openai, createOpenAI } from "@ai-sdk/openai";
|
|
7
|
+
import {
|
|
8
|
+
streamText,
|
|
9
|
+
embed,
|
|
10
|
+
convertToModelMessages,
|
|
11
|
+
createUIMessageStream,
|
|
12
|
+
createUIMessageStreamResponse,
|
|
13
|
+
} from "ai";
|
|
14
|
+
|
|
15
|
+
// Create OpenAI client for embeddings
|
|
16
|
+
const openaiClient = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
17
|
+
|
|
18
|
+
// System prompt for the assistant
|
|
19
|
+
const SYSTEM_PROMPT = `You are a helpful AI assistant with long-term memory powered by Cortex.
|
|
20
|
+
|
|
21
|
+
Your capabilities:
|
|
22
|
+
- You remember everything users tell you across conversations
|
|
23
|
+
- You can recall facts, preferences, and context from past interactions
|
|
24
|
+
- You naturally reference what you've learned about the user
|
|
25
|
+
|
|
26
|
+
Behavior guidelines:
|
|
27
|
+
- When you remember something from a previous conversation, mention it naturally
|
|
28
|
+
- If asked about something you learned, reference it specifically
|
|
29
|
+
- Be conversational and friendly
|
|
30
|
+
- Help demonstrate the memory system by showing what you remember
|
|
31
|
+
|
|
32
|
+
Example interactions:
|
|
33
|
+
- User: "My name is Alex" → Remember and use their name
|
|
34
|
+
- User: "I work at Acme Corp" → Remember their employer
|
|
35
|
+
- User: "My favorite color is blue" → Remember their preference
|
|
36
|
+
- User: "What do you know about me?" → List everything you remember`;
|
|
37
|
+
|
|
38
|
+
// Create Cortex Memory config factory
|
|
39
|
+
// Uses createCortexMemoryAsync for graph support when CORTEX_GRAPH_SYNC=true
|
|
40
|
+
function getCortexMemoryConfig(
|
|
41
|
+
memorySpaceId: string,
|
|
42
|
+
userId: string,
|
|
43
|
+
layerObserver?: LayerObserver,
|
|
44
|
+
): CortexMemoryConfig {
|
|
45
|
+
return {
|
|
46
|
+
convexUrl: process.env.CONVEX_URL!,
|
|
47
|
+
memorySpaceId,
|
|
48
|
+
|
|
49
|
+
// User identification
|
|
50
|
+
userId,
|
|
51
|
+
userName: "Demo User",
|
|
52
|
+
|
|
53
|
+
// Agent identification (required for user-agent conversations in SDK v0.17.0+)
|
|
54
|
+
agentId: "quickstart-assistant",
|
|
55
|
+
agentName: "Cortex Demo Assistant",
|
|
56
|
+
|
|
57
|
+
// Enable graph memory sync (auto-configured via env vars)
|
|
58
|
+
// When true, uses CypherGraphAdapter to sync to Neo4j/Memgraph
|
|
59
|
+
enableGraphMemory: process.env.CORTEX_GRAPH_SYNC === "true",
|
|
60
|
+
|
|
61
|
+
// Enable fact extraction (auto-configured via env vars)
|
|
62
|
+
enableFactExtraction: process.env.CORTEX_FACT_EXTRACTION === "true",
|
|
63
|
+
|
|
64
|
+
// Belief Revision (v0.24.0+)
|
|
65
|
+
// Automatically handles fact updates, supersessions, and deduplication
|
|
66
|
+
// When a user changes their preference (e.g., "I now prefer purple"),
|
|
67
|
+
// the system intelligently updates or supersedes the old fact.
|
|
68
|
+
beliefRevision: {
|
|
69
|
+
enabled: true, // Enable the belief revision pipeline
|
|
70
|
+
slotMatching: true, // Fast slot-based conflict detection (subject-predicate matching)
|
|
71
|
+
llmResolution: true, // LLM-based resolution for nuanced conflicts
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Embedding provider for semantic matching (required for semantic dedup & belief revision)
|
|
75
|
+
embeddingProvider: {
|
|
76
|
+
generate: async (text: string) => {
|
|
77
|
+
const result = await embed({
|
|
78
|
+
model: openaiClient.embedding("text-embedding-3-small"),
|
|
79
|
+
value: text,
|
|
80
|
+
});
|
|
81
|
+
return result.embedding;
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// Streaming enhancements
|
|
86
|
+
streamingOptions: {
|
|
87
|
+
storePartialResponse: true,
|
|
88
|
+
progressiveFactExtraction: true,
|
|
89
|
+
enableAdaptiveProcessing: true,
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// Memory recall configuration (v0.23.0 - unified retrieval across all layers)
|
|
93
|
+
memorySearchLimit: 20, // Results from combined vector + facts + graph search
|
|
94
|
+
|
|
95
|
+
// Real-time layer tracking (v0.24.0+)
|
|
96
|
+
// Events are emitted as each layer processes, enabling live UI updates
|
|
97
|
+
layerObserver,
|
|
98
|
+
|
|
99
|
+
// Debug in development
|
|
100
|
+
debug: process.env.NODE_ENV === "development",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function POST(req: Request) {
|
|
105
|
+
try {
|
|
106
|
+
const body = await req.json();
|
|
107
|
+
const { messages, memorySpaceId, userId } = body;
|
|
108
|
+
|
|
109
|
+
// Convert UIMessage[] from useChat to ModelMessage[] for streamText
|
|
110
|
+
// Note: In AI SDK v6+, convertToModelMessages may return a Promise
|
|
111
|
+
const modelMessagesResult = convertToModelMessages(messages);
|
|
112
|
+
const modelMessages =
|
|
113
|
+
modelMessagesResult instanceof Promise
|
|
114
|
+
? await modelMessagesResult
|
|
115
|
+
: modelMessagesResult;
|
|
116
|
+
|
|
117
|
+
// Use createUIMessageStream to send both LLM text and layer events
|
|
118
|
+
return createUIMessageStreamResponse({
|
|
119
|
+
stream: createUIMessageStream({
|
|
120
|
+
execute: async ({ writer }) => {
|
|
121
|
+
// Create observer that writes layer events to the stream
|
|
122
|
+
// These events are transient (not persisted in message history)
|
|
123
|
+
const layerObserver: LayerObserver = {
|
|
124
|
+
onOrchestrationStart: (orchestrationId) => {
|
|
125
|
+
writer.write({
|
|
126
|
+
type: "data-orchestration-start",
|
|
127
|
+
data: { orchestrationId },
|
|
128
|
+
transient: true,
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
onLayerUpdate: (event) => {
|
|
132
|
+
writer.write({
|
|
133
|
+
type: "data-layer-update",
|
|
134
|
+
data: {
|
|
135
|
+
layer: event.layer,
|
|
136
|
+
status: event.status,
|
|
137
|
+
timestamp: event.timestamp,
|
|
138
|
+
latencyMs: event.latencyMs,
|
|
139
|
+
data: event.data,
|
|
140
|
+
error: event.error,
|
|
141
|
+
revisionAction: event.revisionAction,
|
|
142
|
+
supersededFacts: event.supersededFacts,
|
|
143
|
+
},
|
|
144
|
+
transient: true,
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
onOrchestrationComplete: (summary) => {
|
|
148
|
+
writer.write({
|
|
149
|
+
type: "data-orchestration-complete",
|
|
150
|
+
data: {
|
|
151
|
+
orchestrationId: summary.orchestrationId,
|
|
152
|
+
totalLatencyMs: summary.totalLatencyMs,
|
|
153
|
+
createdIds: summary.createdIds,
|
|
154
|
+
},
|
|
155
|
+
transient: true,
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Build config with the observer
|
|
161
|
+
const config = getCortexMemoryConfig(
|
|
162
|
+
memorySpaceId || "quickstart-demo",
|
|
163
|
+
userId || "demo-user",
|
|
164
|
+
layerObserver,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// Create memory-augmented model with async initialization (enables graph support)
|
|
168
|
+
// This connects to Neo4j/Memgraph if CORTEX_GRAPH_SYNC=true
|
|
169
|
+
const cortexMemory = await createCortexMemoryAsync(config);
|
|
170
|
+
|
|
171
|
+
// Stream response with automatic memory integration
|
|
172
|
+
const result = streamText({
|
|
173
|
+
model: cortexMemory(openai("gpt-4o-mini")),
|
|
174
|
+
messages: modelMessages,
|
|
175
|
+
system: SYSTEM_PROMPT,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Merge LLM stream into the UI message stream
|
|
179
|
+
writer.merge(result.toUIMessageStream());
|
|
180
|
+
},
|
|
181
|
+
}),
|
|
182
|
+
});
|
|
183
|
+
} catch (error) {
|
|
184
|
+
console.error("[Chat API Error]", error);
|
|
185
|
+
|
|
186
|
+
return new Response(
|
|
187
|
+
JSON.stringify({
|
|
188
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
189
|
+
}),
|
|
190
|
+
{
|
|
191
|
+
status: 500,
|
|
192
|
+
headers: { "Content-Type": "application/json" },
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Cortex } from "@cortexmemory/sdk";
|
|
2
|
+
|
|
3
|
+
export const dynamic = "force-dynamic";
|
|
4
|
+
|
|
5
|
+
function getCortex() {
|
|
6
|
+
return new Cortex({ convexUrl: process.env.CONVEX_URL! });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function GET(req: Request) {
|
|
10
|
+
try {
|
|
11
|
+
const { searchParams } = new URL(req.url);
|
|
12
|
+
const memorySpaceId =
|
|
13
|
+
searchParams.get("memorySpaceId") || "quickstart-demo";
|
|
14
|
+
const userId = searchParams.get("userId");
|
|
15
|
+
const limit = parseInt(searchParams.get("limit") || "50");
|
|
16
|
+
|
|
17
|
+
const cortex = getCortex();
|
|
18
|
+
|
|
19
|
+
// Fetch facts for the user/memory space
|
|
20
|
+
const facts = await cortex.facts.list({
|
|
21
|
+
memorySpaceId,
|
|
22
|
+
...(userId ? { userId } : {}),
|
|
23
|
+
limit,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return Response.json({
|
|
27
|
+
facts,
|
|
28
|
+
count: facts.length,
|
|
29
|
+
memorySpaceId,
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("[Facts API Error]", error);
|
|
33
|
+
|
|
34
|
+
return Response.json(
|
|
35
|
+
{ error: error instanceof Error ? error.message : "Unknown error" },
|
|
36
|
+
{ status: 500 },
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|