mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-10 22:41:17 +00:00
add support for responses api in openai typescript sdk
This commit is contained in:
parent
af12864d72
commit
ba6ae0b215
2 changed files with 147 additions and 7 deletions
|
|
@ -6,11 +6,13 @@ import {
|
|||
|
||||
/**
|
||||
* Wraps an OpenAI client with SuperMemory middleware to automatically inject relevant memories
|
||||
* into the system prompt based on the user's message content.
|
||||
* into both Chat Completions and Responses APIs based on the user's input content.
|
||||
*
|
||||
* This middleware searches the supermemory API for relevant memories using the container tag
|
||||
* and user message, then either appends memories to an existing system prompt or creates
|
||||
* a new system prompt with the memories.
|
||||
* For Chat Completions API: Searches for memories using the user message content and injects
|
||||
* them into the system prompt (appends to existing or creates new system prompt).
|
||||
*
|
||||
* For Responses API: Searches for memories using the input parameter and injects them into
|
||||
* the instructions parameter (appends to existing or creates new instructions).
|
||||
*
|
||||
* @param openaiClient - The OpenAI client to wrap with SuperMemory middleware
|
||||
* @param containerTag - The container tag/identifier for memory search (e.g., user ID, project ID)
|
||||
|
|
@ -20,7 +22,7 @@ import {
|
|||
* @param options.mode - Optional mode for memory search: "profile" (default), "query", or "full"
|
||||
* @param options.addMemory - Optional mode for memory addition: "always", "never" (default)
|
||||
*
|
||||
* @returns An OpenAI client with SuperMemory middleware injected
|
||||
* @returns An OpenAI client with SuperMemory middleware injected for both Chat Completions and Responses APIs
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
|
|
@ -37,13 +39,20 @@ import {
|
|||
* addMemory: "always"
|
||||
* })
|
||||
*
|
||||
* // Use normally - memories will be automatically injected
|
||||
* const response = await openaiWithSupermemory.chat.completions.create({
|
||||
* // Use with Chat Completions API - memories injected into system prompt
|
||||
* const chatResponse = await openaiWithSupermemory.chat.completions.create({
|
||||
* model: "gpt-4",
|
||||
* messages: [
|
||||
* { role: "user", content: "What's my favorite programming language?" }
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Use with Responses API - memories injected into instructions
|
||||
* const response = await openaiWithSupermemory.responses.create({
|
||||
* model: "gpt-4o",
|
||||
* instructions: "You are a helpful coding assistant",
|
||||
* input: "What's my favorite programming language?"
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @throws {Error} When SUPERMEMORY_API_KEY environment variable is not set
|
||||
|
|
|
|||
|
|
@ -338,7 +338,132 @@ export function createOpenAIMiddleware(
|
|||
apiKey: process.env.SUPERMEMORY_API_KEY,
|
||||
})
|
||||
|
||||
const conversationId = options?.conversationId
|
||||
const mode = options?.mode ?? "profile"
|
||||
const addMemory = options?.addMemory ?? "never"
|
||||
|
||||
const originalCreate = openaiClient.chat.completions.create
|
||||
const originalResponsesCreate = openaiClient.responses?.create
|
||||
|
||||
/**
|
||||
* Formats memories for injection into Responses API instructions.
|
||||
*
|
||||
* Searches for relevant memories and formats them for inclusion in the
|
||||
* instructions parameter of the Responses API.
|
||||
*
|
||||
* @param input - The input text from the Responses API call
|
||||
* @param containerTag - The container tag for memory search
|
||||
* @param logger - Logger instance
|
||||
* @param mode - Memory search mode
|
||||
* @returns Formatted memories string for instructions
|
||||
*/
|
||||
const getMemoriesForInstructions = async (
|
||||
input: string,
|
||||
containerTag: string,
|
||||
logger: Logger,
|
||||
mode: "profile" | "query" | "full",
|
||||
) => {
|
||||
const queryText = mode !== "profile" ? input : ""
|
||||
|
||||
const memoriesResponse = await supermemoryProfileSearch(
|
||||
containerTag,
|
||||
queryText,
|
||||
)
|
||||
|
||||
const memoryCountStatic = memoriesResponse.profile.static?.length || 0
|
||||
const memoryCountDynamic = memoriesResponse.profile.dynamic?.length || 0
|
||||
|
||||
logger.info("Memory search completed for Responses API", {
|
||||
containerTag,
|
||||
memoryCountStatic,
|
||||
memoryCountDynamic,
|
||||
queryText:
|
||||
queryText.substring(0, 100) + (queryText.length > 100 ? "..." : ""),
|
||||
mode,
|
||||
})
|
||||
|
||||
const profileData =
|
||||
mode !== "query"
|
||||
? convertProfileToMarkdown({
|
||||
profile: {
|
||||
static: memoriesResponse.profile.static?.map((item) => item.memory),
|
||||
dynamic: memoriesResponse.profile.dynamic?.map(
|
||||
(item) => item.memory,
|
||||
),
|
||||
},
|
||||
searchResults: {
|
||||
results: memoriesResponse.searchResults.results.map((item) => ({
|
||||
memory: item.memory,
|
||||
})) as [{ memory: string }],
|
||||
},
|
||||
})
|
||||
: ""
|
||||
const searchResultsMemories =
|
||||
mode !== "profile"
|
||||
? `Search results for user's input: \n${memoriesResponse.searchResults.results
|
||||
.map((result) => `- ${result.memory}`)
|
||||
.join("\n")}`
|
||||
: ""
|
||||
|
||||
const memories = `${profileData}\n${searchResultsMemories}`.trim()
|
||||
|
||||
if (memories) {
|
||||
logger.debug("Memory content preview for Responses API", {
|
||||
content: memories,
|
||||
fullLength: memories.length,
|
||||
})
|
||||
}
|
||||
|
||||
return memories
|
||||
}
|
||||
|
||||
const createResponsesWithMemory = async (
|
||||
params: Parameters<typeof originalResponsesCreate>[0],
|
||||
) => {
|
||||
if (!originalResponsesCreate) {
|
||||
throw new Error("Responses API is not available in this OpenAI client version")
|
||||
}
|
||||
|
||||
const input = typeof params.input === "string" ? params.input : ""
|
||||
|
||||
if (addMemory === "always" && input?.trim()) {
|
||||
const content = conversationId
|
||||
? `Input: ${input}`
|
||||
: input
|
||||
const customId = conversationId
|
||||
? `conversation:${conversationId}`
|
||||
: undefined
|
||||
|
||||
addMemoryTool(client, containerTag, content, customId, logger)
|
||||
}
|
||||
|
||||
if (mode !== "profile" && !input) {
|
||||
logger.debug("No input found for Responses API, skipping memory search")
|
||||
return originalResponsesCreate.call(openaiClient.responses, params)
|
||||
}
|
||||
|
||||
logger.info("Starting memory search for Responses API", {
|
||||
containerTag,
|
||||
conversationId,
|
||||
mode,
|
||||
})
|
||||
|
||||
const memories = await getMemoriesForInstructions(
|
||||
input,
|
||||
containerTag,
|
||||
logger,
|
||||
mode,
|
||||
)
|
||||
|
||||
const enhancedInstructions = memories
|
||||
? `${params.instructions || ""}\n\n${memories}`.trim()
|
||||
: params.instructions
|
||||
|
||||
return originalResponsesCreate.call(openaiClient.responses, {
|
||||
...params,
|
||||
instructions: enhancedInstructions,
|
||||
})
|
||||
}
|
||||
|
||||
const createWithMemory = async (
|
||||
params: OpenAI.Chat.Completions.ChatCompletionCreateParams,
|
||||
|
|
@ -389,5 +514,11 @@ export function createOpenAIMiddleware(
|
|||
openaiClient.chat.completions.create =
|
||||
createWithMemory as typeof originalCreate
|
||||
|
||||
// Wrap Responses API if available
|
||||
if (originalResponsesCreate) {
|
||||
openaiClient.responses.create =
|
||||
createResponsesWithMemory as typeof originalResponsesCreate
|
||||
}
|
||||
|
||||
return openaiClient
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue