add support for responses api in openai typescript sdk

This commit is contained in:
Shoubhit Dash 2025-11-01 21:19:31 +05:30 committed by Mahesh Sanikommmu
parent af12864d72
commit ba6ae0b215
2 changed files with 147 additions and 7 deletions

View file

@ -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

View file

@ -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
}