fix: remove trailing whitespace in processor.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
claude[bot] 2026-04-04 04:53:55 +00:00 committed by Sreeram Sreedhar
parent ffae0b3d37
commit 250dae7200
7 changed files with 168 additions and 166 deletions

View file

@ -34,9 +34,9 @@ const agent = new Agent(withSupermemory(
model: openai("gpt-4o"),
instructions: "You are a helpful assistant.",
},
"user-123", // containerTag - scopes memories to this user
"conv-456", // conversationId - groups messages into the same document
{
containerTag: "user-123", // scopes memories to this user
customId: "conv-456", // groups messages into the same document
mode: "full",
addMemory: "always",
}
@ -51,9 +51,11 @@ const response = await agent.generate("What do you know about me?")
```typescript
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), ... },
"user-123",
"conv-456",
{ addMemory: "always" }
{
containerTag: "user-123",
customId: "conv-456",
addMemory: "always",
}
))
```
</Note>
@ -108,19 +110,19 @@ sequenceDiagram
**Profile Mode (Default)** - Retrieves the user's complete profile without query-based filtering:
```typescript
const agent = new Agent(withSupermemory(config, "user-123", "conv-456", { mode: "profile" }))
const agent = new Agent(withSupermemory(config, { containerTag: "user-123", customId: "conv-456", mode: "profile" }))
```
**Query Mode** - Searches memories based on the user's message:
```typescript
const agent = new Agent(withSupermemory(config, "user-123", "conv-456", { mode: "query" }))
const agent = new Agent(withSupermemory(config, { containerTag: "user-123", customId: "conv-456", mode: "query" }))
```
**Full Mode** - Combines profile AND query-based search for maximum context:
```typescript
const agent = new Agent(withSupermemory(config, "user-123", "conv-456", { mode: "full" }))
const agent = new Agent(withSupermemory(config, { containerTag: "user-123", customId: "conv-456", mode: "full" }))
### Mode Comparison
@ -134,14 +136,16 @@ const agent = new Agent(withSupermemory(config, "user-123", "conv-456", { mode:
## Saving Conversations
Enable automatic conversation saving with `addMemory: "always"`. The `conversationId` parameter groups messages into the same document:
Enable automatic conversation saving with `addMemory: "always"`. The `customId` parameter groups messages into the same document:
```typescript
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
"user-123",
"conv-456",
{ addMemory: "always" }
{
containerTag: "user-123",
customId: "conv-456",
addMemory: "always",
}
))
// All messages in this conversation are saved
@ -173,9 +177,9 @@ const claudePrompt = (data: MemoryPromptData) => `
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
"user-123",
"conv-456",
{
containerTag: "user-123",
customId: "conv-456",
mode: "full",
promptTemplate: claudePrompt,
}
@ -202,7 +206,9 @@ const agent = new Agent({
name: "My Assistant",
model: openai("gpt-4o"),
inputProcessors: [
createSupermemoryProcessor("user-123", "conv-456", {
createSupermemoryProcessor({
containerTag: "user-123",
customId: "conv-456",
mode: "full",
verbose: true,
}),
@ -224,7 +230,9 @@ const agent = new Agent({
name: "My Assistant",
model: openai("gpt-4o"),
outputProcessors: [
createSupermemoryOutputProcessor("user-123", "conv-456", {
createSupermemoryOutputProcessor({
containerTag: "user-123",
customId: "conv-456",
addMemory: "always",
}),
],
@ -240,7 +248,9 @@ import { Agent } from "@mastra/core/agent"
import { createSupermemoryProcessors } from "@supermemory/tools/mastra"
import { openai } from "@ai-sdk/openai"
const { input, output } = createSupermemoryProcessors("user-123", "conv-456", {
const { input, output } = createSupermemoryProcessors({
containerTag: "user-123",
customId: "conv-456",
mode: "full",
addMemory: "always",
verbose: true,
@ -259,7 +269,7 @@ const agent = new Agent({
## Using RequestContext
Mastra's `RequestContext` can provide a dynamic conversation ID override:
Mastra's `RequestContext` can provide a dynamic custom ID override:
```typescript
import { Agent } from "@mastra/core/agent"
@ -269,15 +279,15 @@ import { openai } from "@ai-sdk/openai"
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
"user-123",
"default-conv-id",
{
containerTag: "user-123",
customId: "default-conv-id",
mode: "full",
addMemory: "always",
}
))
// Override conversationId dynamically via RequestContext
// Override customId dynamically via RequestContext
const ctx = new RequestContext()
ctx.set(MASTRA_THREAD_ID_KEY, "dynamic-thread-id")
@ -293,9 +303,11 @@ Enable detailed logging for debugging:
```typescript
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
"user-123",
"conv-456",
{ verbose: true }
{
containerTag: "user-123",
customId: "conv-456",
verbose: true,
}
))
// Console output:
@ -321,8 +333,10 @@ const agent = new Agent(withSupermemory(
inputProcessors: [myLoggingProcessor],
outputProcessors: [myAnalyticsProcessor],
},
"user-123",
"conv-456"
{
containerTag: "user-123",
customId: "conv-456",
}
))
```
@ -337,17 +351,13 @@ Enhances a Mastra agent config with memory capabilities.
```typescript
function withSupermemory<T extends AgentConfig>(
config: T,
containerTag: string,
conversationId: string,
options?: SupermemoryMastraOptions
options: SupermemoryMastraOptions
): T
```
**Parameters:**
- `config` - The Mastra agent configuration object
- `containerTag` - User/container ID for scoping memories
- `conversationId` - Conversation ID to group messages into the same document
- `options` - Configuration options
- `options` - Configuration options including `containerTag` and `customId`
**Returns:** Enhanced config with Supermemory processors injected
@ -357,9 +367,7 @@ Creates an input processor for memory injection.
```typescript
function createSupermemoryProcessor(
containerTag: string,
conversationId: string,
options?: SupermemoryMastraOptions
options: SupermemoryMastraOptions
): SupermemoryInputProcessor
```
@ -369,9 +377,7 @@ Creates an output processor for conversation saving.
```typescript
function createSupermemoryOutputProcessor(
containerTag: string,
conversationId: string,
options?: SupermemoryMastraOptions
options: SupermemoryMastraOptions
): SupermemoryOutputProcessor
```
@ -381,9 +387,7 @@ Creates both processors with shared configuration.
```typescript
function createSupermemoryProcessors(
containerTag: string,
conversationId: string,
options?: SupermemoryMastraOptions
options: SupermemoryMastraOptions
): {
input: SupermemoryInputProcessor
output: SupermemoryOutputProcessor
@ -394,6 +398,8 @@ function createSupermemoryProcessors(
```typescript
interface SupermemoryMastraOptions {
containerTag: string // User/container ID for scoping memories
customId: string // Custom ID to group messages into the same document
apiKey?: string
baseUrl?: string
mode?: "profile" | "query" | "full"
@ -419,15 +425,17 @@ Processors gracefully handle errors without breaking the agent:
- **API errors** - Logged and skipped; agent continues without memories
- **Missing API key** - Throws immediately with helpful error message
- **Empty conversationId** - Throws immediately with helpful `[supermemory]`-prefixed error message
- **Empty customId** - Throws immediately with helpful `[supermemory]`-prefixed error message
```typescript
// Missing API key throws immediately
const agent = new Agent(withSupermemory(
{ id: "my-assistant", model: openai("gpt-4o"), instructions: "..." },
"user-123",
"conv-456",
{ apiKey: undefined } // Will check SUPERMEMORY_API_KEY env
{
containerTag: "user-123",
customId: "conv-456",
apiKey: undefined, // Will check SUPERMEMORY_API_KEY env
}
))
// Error: SUPERMEMORY_API_KEY is not set
```

View file

@ -430,17 +430,17 @@ createSupermemoryProcessors("user-123", "conv-456", { mode: "full" })
// New API - clearer with explicit key-value pairs
withSupermemory(config, {
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full"
})
new SupermemoryInputProcessor({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full"
})
createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full"
})
```
@ -464,7 +464,7 @@ const agent = new Agent(withSupermemory(
},
{
containerTag: "user-123", // scopes memories to this user
conversationId: "conv-456", // groups messages into the same document
customId: "conv-456", // groups messages into the same document
mode: "full",
addMemory: "always",
}
@ -485,7 +485,7 @@ import { openai } from "@ai-sdk/openai"
const { input, output } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full",
addMemory: "always",
verbose: true, // Enable logging
@ -514,11 +514,11 @@ import { openai } from "@ai-sdk/openai"
async function main() {
const userId = "user-alex-123"
const conversationId = `conv-${Date.now()}`
const customId = `conv-${Date.now()}`
const { input, output } = createSupermemoryProcessors({
containerTag: userId,
conversationId: conversationId,
customId: customId,
mode: "profile", // Fetch user profile memories
addMemory: "always", // Save all conversations
verbose: true,
@ -558,21 +558,21 @@ main()
// Profile mode - good for general personalization
const { input } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "profile"
})
// Query mode - good for specific lookups
const { input } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "query"
})
// Full mode - comprehensive context
const { input } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full"
})
```
@ -593,15 +593,15 @@ ${data.generalSearchMemories}
const { input, output } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "conv-456",
customId: "conv-456",
mode: "full",
promptTemplate: customTemplate,
})
```
#### Using RequestContext for Dynamic Conversation IDs
#### Using RequestContext for Dynamic Custom IDs
Mastra's RequestContext can override the `conversationId` dynamically per request:
Mastra's RequestContext can override the `customId` dynamically per request:
```typescript
import { Agent } from "@mastra/core/agent"
@ -610,7 +610,7 @@ import { createSupermemoryProcessors } from "@supermemory/tools/mastra"
const { input, output } = createSupermemoryProcessors({
containerTag: "user-123",
conversationId: "default-conv-id",
customId: "default-conv-id",
mode: "profile",
addMemory: "always",
})
@ -623,7 +623,7 @@ const agent = new Agent({
outputProcessors: [output],
})
// Override conversationId dynamically per request
// Override customId dynamically per request
const ctx = new RequestContext()
ctx.set(MASTRA_THREAD_ID_KEY, "dynamic-thread-123")

View file

@ -43,7 +43,7 @@ import type {
*/
interface ProcessorContext {
containerTag: string
conversationId: string
customId: string
apiKey: string
baseUrl: string
mode: MemoryMode
@ -59,7 +59,7 @@ interface ProcessorContext {
function createProcessorContext(
options: SupermemoryMastraOptions,
): ProcessorContext {
const { containerTag, conversationId } = options
const { containerTag, customId } = options
if (
!containerTag ||
@ -68,16 +68,16 @@ function createProcessorContext(
) {
throw new Error(
"[supermemory] containerTag is required and must be a non-empty string. " +
"Pass it in the options object: new SupermemoryInputProcessor({ containerTag: 'user-123', conversationId: 'conv-456' })",
"Pass it in the options object: new SupermemoryInputProcessor({ containerTag: 'user-123', customId: 'conv-456' })",
)
}
if (typeof conversationId !== "string" || !conversationId.trim()) {
if (typeof customId !== "string" || !customId.trim()) {
throw new Error(
"[supermemory] conversationId is required and must be a non-empty string. " +
"[supermemory] customId is required and must be a non-empty string. " +
"Pass a unique identifier (e.g., session ID, chat ID) in the options object. " +
"This ensures messages are grouped into the same document for a conversation. " +
"Example: new SupermemoryInputProcessor({ containerTag: 'user-123', conversationId: 'conversation-456' })",
"Example: new SupermemoryInputProcessor({ containerTag: 'user-123', customId: 'conversation-456' })",
)
}
@ -87,7 +87,7 @@ function createProcessorContext(
return {
containerTag,
conversationId,
customId,
apiKey,
baseUrl,
mode: options.mode ?? "profile",
@ -99,13 +99,13 @@ function createProcessorContext(
}
/**
* Gets the effective conversationId from context or RequestContext.
* Gets the effective customId from context or RequestContext.
*
* Priority order:
* 1. RequestContext
* 2. Default conversationId from processor options
* 1. RequestContext
* 2. Default customId from processor options
*/
function getEffectiveConversationId(
function getEffectiveCustomId(
ctx: ProcessorContext,
requestContext?: RequestContext,
): string {
@ -116,8 +116,8 @@ function getEffectiveConversationId(
| undefined
if (fromCtx) return fromCtx
}
// Fall back to required default conversationId
return ctx.conversationId
// Fall back to required default customId
return ctx.customId
}
/**
@ -140,7 +140,7 @@ function getEffectiveConversationId(
* inputProcessors: [
* new SupermemoryInputProcessor({
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* mode: "full",
* verbose: true,
* }),
@ -175,13 +175,10 @@ export class SupermemoryInputProcessor implements Processor {
return messageList
}
const effectiveConversationId = getEffectiveConversationId(
this.ctx,
requestContext,
)
const effectiveCustomId = getEffectiveCustomId(this.ctx, requestContext)
const turnKey = MemoryCache.makeTurnKey(
this.ctx.containerTag,
effectiveConversationId,
effectiveCustomId,
this.ctx.mode,
queryText || "",
)
@ -195,7 +192,7 @@ export class SupermemoryInputProcessor implements Processor {
this.ctx.logger.info("Starting memory search", {
containerTag: this.ctx.containerTag,
conversationId: effectiveConversationId,
customId: effectiveCustomId,
mode: this.ctx.mode,
})
@ -247,7 +244,7 @@ export class SupermemoryInputProcessor implements Processor {
* outputProcessors: [
* new SupermemoryOutputProcessor({
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* addMemory: "always",
* }),
* ],
@ -273,10 +270,7 @@ export class SupermemoryOutputProcessor implements Processor {
return messages
}
const effectiveConversationId = getEffectiveConversationId(
this.ctx,
requestContext,
)
const effectiveCustomId = getEffectiveCustomId(this.ctx, requestContext)
try {
const conversationMessages = this.convertToConversationMessages(messages)
@ -287,7 +281,7 @@ export class SupermemoryOutputProcessor implements Processor {
}
const response = await addConversation({
conversationId: effectiveConversationId,
conversationId: effectiveCustomId,
messages: conversationMessages,
containerTags: [this.ctx.containerTag],
apiKey: this.ctx.apiKey,
@ -296,7 +290,7 @@ export class SupermemoryOutputProcessor implements Processor {
this.ctx.logger.info("Conversation saved successfully", {
containerTag: this.ctx.containerTag,
conversationId: effectiveConversationId,
customId: effectiveCustomId,
messageCount: conversationMessages.length,
responseId: response.id,
})
@ -353,7 +347,7 @@ export class SupermemoryOutputProcessor implements Processor {
/**
* Creates a Supermemory input processor for memory injection.
*
* @param options - Configuration options including containerTag and conversationId
* @param options - Configuration options including containerTag and customId
* @returns Configured SupermemoryInputProcessor instance
*
* @example
@ -364,7 +358,7 @@ export class SupermemoryOutputProcessor implements Processor {
*
* const processor = createSupermemoryProcessor({
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* mode: "full",
* verbose: true,
* })
@ -386,7 +380,7 @@ export function createSupermemoryProcessor(
/**
* Creates a Supermemory output processor for saving conversations.
*
* @param options - Configuration options including containerTag and conversationId
* @param options - Configuration options including containerTag and customId
* @returns Configured SupermemoryOutputProcessor instance
*
* @example
@ -397,7 +391,7 @@ export function createSupermemoryProcessor(
*
* const processor = createSupermemoryOutputProcessor({
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* addMemory: "always",
* })
*
@ -421,7 +415,7 @@ export function createSupermemoryOutputProcessor(
* Use this when you want both memory injection and conversation saving
* with consistent settings across both processors.
*
* @param options - Configuration options shared by both processors including containerTag and conversationId
* @param options - Configuration options shared by both processors including containerTag and customId
* @returns Object containing both input and output processors
*
* @example
@ -432,7 +426,7 @@ export function createSupermemoryOutputProcessor(
*
* const { input, output } = createSupermemoryProcessors({
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* mode: "full",
* addMemory: "always",
* })

View file

@ -43,9 +43,9 @@ export interface SupermemoryMastraOptions extends SupermemoryBaseOptions {
containerTag: string
/**
* Conversation ID for grouping messages into the same document
* Custom ID for grouping messages into the same document (e.g., conversation ID)
*/
conversationId: string
customId: string
}
export type { PromptTemplate, MemoryMode, AddMemoryMode, MemoryPromptData }

View file

@ -37,7 +37,7 @@ interface AgentConfig {
* - Output processor: Optionally saves conversations after responses
*
* @param config - The Mastra agent configuration to enhance
* @param options - Configuration options including containerTag, conversationId, and memory behavior
* @param options - Configuration options including containerTag, customId, and memory behavior
* @returns Enhanced agent config with Supermemory processors injected
*
* @example
@ -55,7 +55,7 @@ interface AgentConfig {
* },
* {
* containerTag: "user-123",
* conversationId: "conv-456",
* customId: "conv-456",
* mode: "full",
* addMemory: "always",
* }

View file

@ -37,7 +37,7 @@ const INTEGRATION_CONFIG = {
apiKey: process.env.SUPERMEMORY_API_KEY || "",
baseUrl: process.env.SUPERMEMORY_BASE_URL || "https://api.supermemory.ai",
containerTag: "integration-test-mastra",
conversationId: `integration-test-${Date.now()}`,
customId: `integration-test-${Date.now()}`,
}
const shouldRunIntegration = !!process.env.SUPERMEMORY_API_KEY
@ -126,7 +126,7 @@ describe.skipIf(!shouldRunIntegration)(
it("should fetch real memories and inject into messageList", async () => {
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -152,7 +152,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "query",
@ -191,7 +191,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "full",
@ -225,7 +225,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -260,7 +260,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -284,11 +284,11 @@ describe.skipIf(!shouldRunIntegration)(
it("should save conversation when addMemory is always", async () => {
const fetchSpy = vi.spyOn(globalThis, "fetch")
const conversationId = `test-mastra-${Date.now()}`
const customId = `test-mastra-${Date.now()}`
const processor = new SupermemoryOutputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: conversationId,
customId: customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
addMemory: "always",
@ -318,7 +318,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryOutputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: "test-thread",
customId: "test-thread",
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
addMemory: "never",
@ -343,12 +343,12 @@ describe.skipIf(!shouldRunIntegration)(
fetchSpy.mockRestore()
})
it("should use conversationId from RequestContext when available", async () => {
it("should use customId from RequestContext when available", async () => {
const fetchSpy = vi.spyOn(globalThis, "fetch")
const processor = new SupermemoryOutputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
addMemory: "always",
@ -361,7 +361,7 @@ describe.skipIf(!shouldRunIntegration)(
await processor.processOutputResult(
createOutputArgs({
messages: [
createMessage("user", "Test with RequestContext conversationId"),
createMessage("user", "Test with RequestContext customId"),
createMessage("assistant", "Got it!"),
],
requestContext,
@ -383,7 +383,7 @@ describe.skipIf(!shouldRunIntegration)(
it("should create working input and output processors", async () => {
const { input, output } = createSupermemoryProcessors({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: `processors-test-${Date.now()}`,
customId: `processors-test-${Date.now()}`,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -420,7 +420,7 @@ describe.skipIf(!shouldRunIntegration)(
const enhanced = withSupermemory(config, {
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: `wrapper-test-${Date.now()}`,
customId: `wrapper-test-${Date.now()}`,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -470,7 +470,7 @@ describe.skipIf(!shouldRunIntegration)(
const enhanced = withSupermemory(config, {
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -491,7 +491,7 @@ describe.skipIf(!shouldRunIntegration)(
it("verbose mode should not break functionality", async () => {
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -514,7 +514,7 @@ describe.skipIf(!shouldRunIntegration)(
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: INTEGRATION_CONFIG.apiKey,
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -543,7 +543,7 @@ describe.skipIf(!shouldRunIntegration)(
it("should handle invalid API key gracefully", async () => {
const processor = new SupermemoryInputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: INTEGRATION_CONFIG.conversationId,
customId: INTEGRATION_CONFIG.customId,
apiKey: "invalid-api-key-12345",
baseUrl: INTEGRATION_CONFIG.baseUrl,
mode: "profile",
@ -563,7 +563,7 @@ describe.skipIf(!shouldRunIntegration)(
it("output processor should handle save errors gracefully", async () => {
const processor = new SupermemoryOutputProcessor({
containerTag: INTEGRATION_CONFIG.containerTag,
conversationId: "error-test",
customId: "error-test",
apiKey: "invalid-api-key-12345",
baseUrl: INTEGRATION_CONFIG.baseUrl,
addMemory: "always",

View file

@ -29,7 +29,7 @@ const TEST_CONFIG = {
apiKey: "test-api-key",
baseUrl: "https://api.supermemory.ai",
containerTag: "test-mastra-user",
conversationId: "test-conv-123",
customId: "test-conv-123",
}
interface MockAgentConfig {
@ -101,7 +101,7 @@ const createMockProfileResponse = (
const createMockConversationResponse = () => ({
id: "mem-123",
conversationId: "conv-456",
customId: "conv-456",
status: "created",
})
@ -155,7 +155,7 @@ describe("SupermemoryInputProcessor", () => {
it("should create processor with default options", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(processor.id).toBe("supermemory-input")
expect(processor.name).toBe("Supermemory Memory Injection")
@ -167,7 +167,7 @@ describe("SupermemoryInputProcessor", () => {
expect(() => {
new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
}).toThrow("SUPERMEMORY_API_KEY is not set")
})
@ -177,28 +177,28 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: "custom-key",
})
expect(processor.id).toBe("supermemory-input")
})
it("should throw error if conversationId is empty", () => {
it("should throw error if customId is empty", () => {
expect(() => {
new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "",
customId: "",
})
}).toThrow("[supermemory] conversationId is required")
}).toThrow("[supermemory] customId is required")
})
it("should throw error if conversationId is whitespace", () => {
it("should throw error if customId is whitespace", () => {
expect(() => {
new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: " ",
customId: " ",
})
}).toThrow("[supermemory] conversationId is required")
}).toThrow("[supermemory] customId is required")
})
})
@ -217,7 +217,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "profile",
})
@ -246,7 +246,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "profile",
})
@ -275,7 +275,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "query",
})
@ -298,7 +298,7 @@ describe("SupermemoryInputProcessor", () => {
it("should return messageList in query mode when no user message", async () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "query",
})
@ -323,7 +323,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "profile",
})
@ -340,7 +340,7 @@ describe("SupermemoryInputProcessor", () => {
expect(messageList.addSystem).not.toHaveBeenCalled()
})
it("should use conversationId from requestContext fallback", async () => {
it("should use customId from requestContext fallback", async () => {
fetchMock.mockResolvedValue({
ok: true,
json: () => Promise.resolve(createMockProfileResponse(["Memory"])),
@ -348,7 +348,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "profile",
})
@ -374,7 +374,7 @@ describe("SupermemoryInputProcessor", () => {
const processor = new SupermemoryInputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
mode: "query",
})
@ -428,7 +428,7 @@ describe("SupermemoryOutputProcessor", () => {
it("should create processor with default options", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(processor.id).toBe("supermemory-output")
expect(processor.name).toBe("Supermemory Conversation Save")
@ -444,7 +444,7 @@ describe("SupermemoryOutputProcessor", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -481,7 +481,7 @@ describe("SupermemoryOutputProcessor", () => {
it("should not save conversation when addMemory is never", async () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "never",
})
@ -498,7 +498,7 @@ describe("SupermemoryOutputProcessor", () => {
expect(fetchMock).not.toHaveBeenCalled()
})
it("should use conversationId from requestContext", async () => {
it("should use customId from requestContext", async () => {
fetchMock.mockResolvedValue({
ok: true,
json: () => Promise.resolve(createMockConversationResponse()),
@ -506,7 +506,7 @@ describe("SupermemoryOutputProcessor", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -528,7 +528,7 @@ describe("SupermemoryOutputProcessor", () => {
const callBody = JSON.parse(
(fetchMock.mock.calls[0]?.[1] as { body: string }).body,
)
// Should use the RequestContext override, not the default conversationId
// Should use the RequestContext override, not the default customId
expect(callBody.conversationId).toBe("ctx-thread-789")
})
@ -540,7 +540,7 @@ describe("SupermemoryOutputProcessor", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -572,7 +572,7 @@ describe("SupermemoryOutputProcessor", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -621,7 +621,7 @@ describe("SupermemoryOutputProcessor", () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -640,7 +640,7 @@ describe("SupermemoryOutputProcessor", () => {
it("should not save when no messages to save", async () => {
const processor = new SupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: "conv-456",
customId: "conv-456",
apiKey: TEST_CONFIG.apiKey,
addMemory: "always",
})
@ -674,7 +674,7 @@ describe("Factory functions", () => {
it("should create input processor", () => {
const processor = createSupermemoryProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(processor).toBeInstanceOf(SupermemoryInputProcessor)
expect(processor.id).toBe("supermemory-input")
@ -683,7 +683,7 @@ describe("Factory functions", () => {
it("should pass options to processor", () => {
const processor = createSupermemoryProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: "custom-key",
mode: "full",
})
@ -695,7 +695,7 @@ describe("Factory functions", () => {
it("should create output processor", () => {
const processor = createSupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(processor).toBeInstanceOf(SupermemoryOutputProcessor)
expect(processor.id).toBe("supermemory-output")
@ -704,7 +704,7 @@ describe("Factory functions", () => {
it("should pass options to processor", () => {
const processor = createSupermemoryOutputProcessor({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: "custom-key",
addMemory: "always",
})
@ -716,7 +716,7 @@ describe("Factory functions", () => {
it("should create both input and output processors", () => {
const { input, output } = createSupermemoryProcessors({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(input).toBeInstanceOf(SupermemoryInputProcessor)
expect(output).toBeInstanceOf(SupermemoryOutputProcessor)
@ -725,7 +725,7 @@ describe("Factory functions", () => {
it("should share options between processors", () => {
const { input, output } = createSupermemoryProcessors({
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: "custom-key",
mode: "full",
addMemory: "always",
@ -761,7 +761,7 @@ describe("withSupermemory", () => {
expect(() => {
withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
}).toThrow("SUPERMEMORY_API_KEY is not set")
})
@ -772,7 +772,7 @@ describe("withSupermemory", () => {
const config: MockAgentConfig = { id: "test-agent", name: "Test Agent" }
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
apiKey: "custom-key",
})
@ -786,7 +786,7 @@ describe("withSupermemory", () => {
const config: MockAgentConfig = { id: "test-agent", name: "Test Agent" }
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(enhanced.inputProcessors).toHaveLength(1)
@ -804,7 +804,7 @@ describe("withSupermemory", () => {
}
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(enhanced.id).toBe("test-agent")
@ -826,7 +826,7 @@ describe("withSupermemory", () => {
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(enhanced.inputProcessors).toHaveLength(2)
@ -847,7 +847,7 @@ describe("withSupermemory", () => {
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(enhanced.outputProcessors).toHaveLength(2)
@ -867,7 +867,7 @@ describe("withSupermemory", () => {
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
})
expect(enhanced.inputProcessors).toHaveLength(2)
@ -884,7 +884,7 @@ describe("withSupermemory", () => {
const config: MockAgentConfig = { id: "test-agent", name: "Test Agent" }
const enhanced = withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: TEST_CONFIG.conversationId,
customId: TEST_CONFIG.customId,
mode: "full",
addMemory: "always",
verbose: true,
@ -895,27 +895,27 @@ describe("withSupermemory", () => {
})
})
describe("conversationId validation", () => {
it("should throw error if conversationId is empty", () => {
describe("customId validation", () => {
it("should throw error if customId is empty", () => {
const config: MockAgentConfig = { id: "test-agent", name: "Test Agent" }
expect(() => {
withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: "",
customId: "",
})
}).toThrow("[supermemory] conversationId is required")
}).toThrow("[supermemory] customId is required")
})
it("should throw error if conversationId is whitespace", () => {
it("should throw error if customId is whitespace", () => {
const config: MockAgentConfig = { id: "test-agent", name: "Test Agent" }
expect(() => {
withSupermemory(config, {
containerTag: TEST_CONFIG.containerTag,
conversationId: " ",
customId: " ",
})
}).toThrow("[supermemory] conversationId is required")
}).toThrow("[supermemory] customId is required")
})
})
})