mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
feat(@supermemory/tools): vercel ai sdk compatbile with v5 and v6 (#628)
This commit is contained in:
parent
67e783158b
commit
d095bd234e
5 changed files with 310 additions and 176 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@supermemory/tools",
|
||||
"type": "module",
|
||||
"version": "1.3.61",
|
||||
"version": "1.3.62",
|
||||
"description": "Memory tools for AI SDK and OpenAI function calling with supermemory",
|
||||
"scripts": {
|
||||
"build": "tsdown",
|
||||
|
|
@ -13,13 +13,13 @@
|
|||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^2.0.25",
|
||||
"@ai-sdk/openai": "^2.0.23",
|
||||
"@ai-sdk/provider": "^2.0.0",
|
||||
"ai": "^5.0.29",
|
||||
"openai": "^4.104.0",
|
||||
"supermemory": "^3.0.0-alpha.26",
|
||||
"zod": "^4.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ai-sdk/provider": "^3.0.0",
|
||||
"@total-typescript/tsconfig": "^1.0.4",
|
||||
"@types/bun": "^1.2.21",
|
||||
"dotenv": "^16.6.1",
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
"vitest": "^3.2.4",
|
||||
"@anthropic-ai/sdk": "^0.65.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ai-sdk/provider": "^2.0.0 || ^3.0.0"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
|
|
|||
|
|
@ -1,25 +1,37 @@
|
|||
import type { LanguageModelV2 } from "@ai-sdk/provider"
|
||||
import { wrapLanguageModel } from "ai"
|
||||
import { createSupermemoryMiddleware } from "./middleware"
|
||||
import {
|
||||
type LanguageModel,
|
||||
type LanguageModelCallOptions,
|
||||
type LanguageModelStreamPart,
|
||||
getLastUserMessage,
|
||||
} from "./util"
|
||||
import {
|
||||
createSupermemoryContext,
|
||||
transformParamsWithMemory,
|
||||
extractAssistantResponseText,
|
||||
saveMemoryAfterResponse,
|
||||
} from "./middleware"
|
||||
|
||||
interface WrapVercelLanguageModelOptions {
|
||||
conversationId?: string;
|
||||
verbose?: boolean;
|
||||
mode?: "profile" | "query" | "full";
|
||||
addMemory?: "always" | "never";
|
||||
apiKey?: string;
|
||||
baseUrl?: string;
|
||||
conversationId?: string
|
||||
verbose?: boolean
|
||||
mode?: "profile" | "query" | "full"
|
||||
addMemory?: "always" | "never"
|
||||
apiKey?: string
|
||||
baseUrl?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a language model with supermemory middleware to automatically inject relevant memories
|
||||
* into the system prompt based on the user's message content.
|
||||
*
|
||||
* This middleware searches the supermemory API for relevant memories using the container tag
|
||||
* This wrapper 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.
|
||||
*
|
||||
* @param model - The language model to wrap with supermemory capabilities
|
||||
* Supports both Vercel AI SDK 5 (LanguageModelV2) and SDK 6 (LanguageModelV3) via runtime
|
||||
* detection of `model.specificationVersion`.
|
||||
*
|
||||
* @param model - The language model to wrap with supermemory capabilities (V2 or V3)
|
||||
* @param containerTag - The container tag/identifier for memory search (e.g., user ID, project ID)
|
||||
* @param options - Optional configuration options for the middleware
|
||||
* @param options.conversationId - Optional conversation ID to group messages into a single document for contextual memory generation
|
||||
|
|
@ -51,29 +63,124 @@ interface WrapVercelLanguageModelOptions {
|
|||
* @throws {Error} When neither `options.apiKey` nor `process.env.SUPERMEMORY_API_KEY` are set
|
||||
* @throws {Error} When supermemory API request fails
|
||||
*/
|
||||
const wrapVercelLanguageModel = (
|
||||
model: LanguageModelV2,
|
||||
const wrapVercelLanguageModel = <T extends LanguageModel>(
|
||||
model: T,
|
||||
containerTag: string,
|
||||
options?: WrapVercelLanguageModelOptions,
|
||||
): LanguageModelV2 => {
|
||||
): T => {
|
||||
const providedApiKey = options?.apiKey ?? process.env.SUPERMEMORY_API_KEY
|
||||
|
||||
if (!providedApiKey) {
|
||||
throw new Error("SUPERMEMORY_API_KEY is not set — provide it via `options.apiKey` or set `process.env.SUPERMEMORY_API_KEY`")
|
||||
throw new Error(
|
||||
"SUPERMEMORY_API_KEY is not set — provide it via `options.apiKey` or set `process.env.SUPERMEMORY_API_KEY`",
|
||||
)
|
||||
}
|
||||
|
||||
const conversationId = options?.conversationId
|
||||
const verbose = options?.verbose ?? false
|
||||
const mode = options?.mode ?? "profile"
|
||||
const addMemory = options?.addMemory ?? "never"
|
||||
const baseUrl = options?.baseUrl
|
||||
|
||||
const wrappedModel = wrapLanguageModel({
|
||||
model,
|
||||
middleware: createSupermemoryMiddleware(containerTag, providedApiKey, conversationId, verbose, mode, addMemory, baseUrl),
|
||||
const ctx = createSupermemoryContext({
|
||||
containerTag,
|
||||
apiKey: providedApiKey,
|
||||
conversationId: options?.conversationId,
|
||||
verbose: options?.verbose ?? false,
|
||||
mode: options?.mode ?? "profile",
|
||||
addMemory: options?.addMemory ?? "never",
|
||||
baseUrl: options?.baseUrl,
|
||||
})
|
||||
|
||||
const wrappedModel = {
|
||||
...model,
|
||||
|
||||
doGenerate: async (params: LanguageModelCallOptions) => {
|
||||
try {
|
||||
const transformedParams = await transformParamsWithMemory(params, ctx)
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Union type compatibility between V2 and V3
|
||||
const result = await model.doGenerate(transformedParams as any)
|
||||
|
||||
const userMessage = getLastUserMessage(params)
|
||||
if (ctx.addMemory === "always" && userMessage && userMessage.trim()) {
|
||||
const assistantResponseText = extractAssistantResponseText(
|
||||
result.content as unknown[],
|
||||
)
|
||||
saveMemoryAfterResponse(
|
||||
ctx.client,
|
||||
ctx.containerTag,
|
||||
ctx.conversationId,
|
||||
assistantResponseText,
|
||||
params,
|
||||
ctx.logger,
|
||||
ctx.apiKey,
|
||||
ctx.normalizedBaseUrl,
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
} catch (error) {
|
||||
ctx.logger.error("Error generating response", {
|
||||
error: error instanceof Error ? error.message : "Unknown error",
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
doStream: async (params: LanguageModelCallOptions) => {
|
||||
let generatedText = ""
|
||||
|
||||
try {
|
||||
const transformedParams = await transformParamsWithMemory(params, ctx)
|
||||
|
||||
const { stream, ...rest } = await model.doStream(
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Union type compatibility between V2 and V3
|
||||
transformedParams as any,
|
||||
)
|
||||
|
||||
const transformStream = new TransformStream<
|
||||
LanguageModelStreamPart,
|
||||
LanguageModelStreamPart
|
||||
>({
|
||||
transform(chunk, controller) {
|
||||
if (chunk.type === "text-delta") {
|
||||
generatedText += chunk.delta
|
||||
}
|
||||
controller.enqueue(chunk)
|
||||
},
|
||||
flush: async () => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
if (
|
||||
ctx.addMemory === "always" &&
|
||||
userMessage &&
|
||||
userMessage.trim()
|
||||
) {
|
||||
saveMemoryAfterResponse(
|
||||
ctx.client,
|
||||
ctx.containerTag,
|
||||
ctx.conversationId,
|
||||
generatedText,
|
||||
params,
|
||||
ctx.logger,
|
||||
ctx.apiKey,
|
||||
ctx.normalizedBaseUrl,
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
stream: stream.pipeThrough(transformStream),
|
||||
...rest,
|
||||
}
|
||||
} catch (error) {
|
||||
ctx.logger.error("Error streaming response", {
|
||||
error: error instanceof Error ? error.message : "Unknown error",
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
} as T
|
||||
|
||||
return wrappedModel
|
||||
}
|
||||
|
||||
export { wrapVercelLanguageModel as withSupermemory, type WrapVercelLanguageModelOptions as WithSupermemoryOptions }
|
||||
export {
|
||||
wrapVercelLanguageModel as withSupermemory,
|
||||
type WrapVercelLanguageModelOptions as WithSupermemoryOptions,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import type { LanguageModelV2CallOptions } from "@ai-sdk/provider"
|
||||
import { deduplicateMemories } from "../shared"
|
||||
import type { Logger } from "./logger"
|
||||
import { convertProfileToMarkdown, type ProfileStructure } from "./util"
|
||||
import {
|
||||
type LanguageModelCallOptions,
|
||||
convertProfileToMarkdown,
|
||||
type ProfileStructure,
|
||||
} from "./util"
|
||||
|
||||
export const normalizeBaseUrl = (url?: string): string => {
|
||||
const defaultUrl = "https://api.supermemory.ai"
|
||||
|
|
@ -50,12 +53,12 @@ const supermemoryProfileSearch = async (
|
|||
}
|
||||
|
||||
export const addSystemPrompt = async (
|
||||
params: LanguageModelV2CallOptions,
|
||||
params: LanguageModelCallOptions,
|
||||
containerTag: string,
|
||||
logger: Logger,
|
||||
mode: "profile" | "query" | "full",
|
||||
baseUrl = "https://api.supermemory.ai",
|
||||
) => {
|
||||
): Promise<LanguageModelCallOptions> => {
|
||||
const systemPromptExists = params.prompt.some(
|
||||
(prompt) => prompt.role === "system",
|
||||
)
|
||||
|
|
@ -138,21 +141,22 @@ export const addSystemPrompt = async (
|
|||
|
||||
if (systemPromptExists) {
|
||||
logger.debug("Added memories to existing system prompt")
|
||||
return {
|
||||
...params,
|
||||
prompt: params.prompt.map((prompt) =>
|
||||
prompt.role === "system"
|
||||
? { ...prompt, content: `${prompt.content} \n ${memories}` }
|
||||
: prompt,
|
||||
),
|
||||
}
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Union type compatibility between V2 and V3 prompt types
|
||||
const newPrompt = params.prompt.map((prompt: any) =>
|
||||
prompt.role === "system"
|
||||
? { ...prompt, content: `${prompt.content} \n ${memories}` }
|
||||
: prompt,
|
||||
)
|
||||
return { ...params, prompt: newPrompt } as LanguageModelCallOptions
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
"System prompt does not exist, created system prompt with memories",
|
||||
)
|
||||
return {
|
||||
...params,
|
||||
prompt: [{ role: "system" as const, content: memories }, ...params.prompt],
|
||||
}
|
||||
const newPrompt = [
|
||||
{ role: "system" as const, content: memories },
|
||||
...params.prompt,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: Union type compatibility between V2 and V3 prompt types
|
||||
] as any
|
||||
return { ...params, prompt: newPrompt } as LanguageModelCallOptions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
import type {
|
||||
LanguageModelV2CallOptions,
|
||||
LanguageModelV2Middleware,
|
||||
LanguageModelV2StreamPart,
|
||||
} from "@ai-sdk/provider"
|
||||
import Supermemory from "supermemory"
|
||||
import {
|
||||
addConversation,
|
||||
|
|
@ -10,13 +5,15 @@ import {
|
|||
} from "../conversations-client"
|
||||
import { createLogger, type Logger } from "./logger"
|
||||
import {
|
||||
type LanguageModelCallOptions,
|
||||
type LanguageModelStreamPart,
|
||||
type OutputContentItem,
|
||||
getLastUserMessage,
|
||||
filterOutSupermemories,
|
||||
} from "./util"
|
||||
import { addSystemPrompt, normalizeBaseUrl } from "./memory-prompt"
|
||||
|
||||
const getConversationContent = (params: LanguageModelV2CallOptions) => {
|
||||
export const getConversationContent = (params: LanguageModelCallOptions) => {
|
||||
return params.prompt
|
||||
.filter((msg) => msg.role !== "system" && msg.role !== "tool")
|
||||
.map((msg) => {
|
||||
|
|
@ -35,8 +32,8 @@ const getConversationContent = (params: LanguageModelV2CallOptions) => {
|
|||
.join("\n\n")
|
||||
}
|
||||
|
||||
const convertToConversationMessages = (
|
||||
params: LanguageModelV2CallOptions,
|
||||
export const convertToConversationMessages = (
|
||||
params: LanguageModelCallOptions,
|
||||
assistantResponseText: string,
|
||||
): ConversationMessage[] => {
|
||||
const messages: ConversationMessage[] = []
|
||||
|
|
@ -95,12 +92,12 @@ const convertToConversationMessages = (
|
|||
return messages
|
||||
}
|
||||
|
||||
const addMemoryTool = async (
|
||||
export const saveMemoryAfterResponse = async (
|
||||
client: Supermemory,
|
||||
containerTag: string,
|
||||
conversationId: string | undefined,
|
||||
assistantResponseText: string,
|
||||
params: LanguageModelV2CallOptions,
|
||||
params: LanguageModelCallOptions,
|
||||
logger: Logger,
|
||||
apiKey: string,
|
||||
baseUrl: string,
|
||||
|
|
@ -156,15 +153,40 @@ const addMemoryTool = async (
|
|||
}
|
||||
}
|
||||
|
||||
export const createSupermemoryMiddleware = (
|
||||
containerTag: string,
|
||||
apiKey: string,
|
||||
conversationId?: string,
|
||||
verbose = false,
|
||||
mode: "profile" | "query" | "full" = "profile",
|
||||
addMemory: "always" | "never" = "never",
|
||||
baseUrl?: string,
|
||||
): LanguageModelV2Middleware => {
|
||||
export interface SupermemoryMiddlewareOptions {
|
||||
containerTag: string
|
||||
apiKey: string
|
||||
conversationId?: string
|
||||
verbose?: boolean
|
||||
mode?: "profile" | "query" | "full"
|
||||
addMemory?: "always" | "never"
|
||||
baseUrl?: string
|
||||
}
|
||||
|
||||
export interface SupermemoryMiddlewareContext {
|
||||
client: Supermemory
|
||||
logger: Logger
|
||||
containerTag: string
|
||||
conversationId?: string
|
||||
mode: "profile" | "query" | "full"
|
||||
addMemory: "always" | "never"
|
||||
normalizedBaseUrl: string
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
export const createSupermemoryContext = (
|
||||
options: SupermemoryMiddlewareOptions,
|
||||
): SupermemoryMiddlewareContext => {
|
||||
const {
|
||||
containerTag,
|
||||
apiKey,
|
||||
conversationId,
|
||||
verbose = false,
|
||||
mode = "profile",
|
||||
addMemory = "never",
|
||||
baseUrl,
|
||||
} = options
|
||||
|
||||
const logger = createLogger(verbose)
|
||||
const normalizedBaseUrl = normalizeBaseUrl(baseUrl)
|
||||
|
||||
|
|
@ -176,113 +198,92 @@ export const createSupermemoryMiddleware = (
|
|||
})
|
||||
|
||||
return {
|
||||
transformParams: async ({ params }) => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
|
||||
if (mode !== "profile") {
|
||||
if (!userMessage) {
|
||||
logger.debug("No user message found, skipping memory search")
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Starting memory search", {
|
||||
containerTag,
|
||||
conversationId,
|
||||
mode,
|
||||
})
|
||||
|
||||
const transformedParams = await addSystemPrompt(
|
||||
params,
|
||||
containerTag,
|
||||
logger,
|
||||
mode,
|
||||
normalizedBaseUrl,
|
||||
)
|
||||
return transformedParams
|
||||
},
|
||||
wrapGenerate: async ({ doGenerate, params }) => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
|
||||
try {
|
||||
const result = await doGenerate()
|
||||
const assistantResponse = result.content
|
||||
const assistantResponseText = assistantResponse
|
||||
.map((content) => (content.type === "text" ? content.text : ""))
|
||||
.join("")
|
||||
|
||||
if (addMemory === "always" && userMessage && userMessage.trim()) {
|
||||
addMemoryTool(
|
||||
client,
|
||||
containerTag,
|
||||
conversationId,
|
||||
assistantResponseText,
|
||||
params,
|
||||
logger,
|
||||
apiKey,
|
||||
normalizedBaseUrl,
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
} catch (error) {
|
||||
logger.error("Error generating response", {
|
||||
error: error instanceof Error ? error.message : "Unknown error",
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
wrapStream: async ({ doStream, params }) => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
let generatedText = ""
|
||||
|
||||
try {
|
||||
const { stream, ...rest } = await doStream()
|
||||
const transformStream = new TransformStream<
|
||||
LanguageModelV2StreamPart,
|
||||
LanguageModelV2StreamPart
|
||||
>({
|
||||
transform(chunk, controller) {
|
||||
if (chunk.type === "text-delta") {
|
||||
generatedText += chunk.delta
|
||||
}
|
||||
|
||||
controller.enqueue(chunk)
|
||||
},
|
||||
flush: async () => {
|
||||
const content: OutputContentItem[] = []
|
||||
if (generatedText) {
|
||||
content.push({
|
||||
type: "text",
|
||||
text: generatedText,
|
||||
})
|
||||
}
|
||||
|
||||
if (addMemory === "always" && userMessage && userMessage.trim()) {
|
||||
addMemoryTool(
|
||||
client,
|
||||
containerTag,
|
||||
conversationId,
|
||||
generatedText,
|
||||
params,
|
||||
logger,
|
||||
apiKey,
|
||||
normalizedBaseUrl,
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
stream: stream.pipeThrough(transformStream),
|
||||
...rest,
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Error streaming response", {
|
||||
error: error instanceof Error ? error.message : "Unknown error",
|
||||
})
|
||||
throw error
|
||||
}
|
||||
},
|
||||
client,
|
||||
logger,
|
||||
containerTag,
|
||||
conversationId,
|
||||
mode,
|
||||
addMemory,
|
||||
normalizedBaseUrl,
|
||||
apiKey,
|
||||
}
|
||||
}
|
||||
|
||||
export const transformParamsWithMemory = async (
|
||||
params: LanguageModelCallOptions,
|
||||
ctx: SupermemoryMiddlewareContext,
|
||||
): Promise<LanguageModelCallOptions> => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
|
||||
if (ctx.mode !== "profile") {
|
||||
if (!userMessage) {
|
||||
ctx.logger.debug("No user message found, skipping memory search")
|
||||
return params
|
||||
}
|
||||
}
|
||||
|
||||
ctx.logger.info("Starting memory search", {
|
||||
containerTag: ctx.containerTag,
|
||||
conversationId: ctx.conversationId,
|
||||
mode: ctx.mode,
|
||||
})
|
||||
|
||||
const transformedParams = await addSystemPrompt(
|
||||
params,
|
||||
ctx.containerTag,
|
||||
ctx.logger,
|
||||
ctx.mode,
|
||||
ctx.normalizedBaseUrl,
|
||||
)
|
||||
return transformedParams
|
||||
}
|
||||
|
||||
export const extractAssistantResponseText = (content: unknown[]): string => {
|
||||
return (content as Array<{ type: string; text?: string }>)
|
||||
.map((item) => (item.type === "text" ? item.text || "" : ""))
|
||||
.join("")
|
||||
}
|
||||
|
||||
export const createStreamTransform = (
|
||||
ctx: SupermemoryMiddlewareContext,
|
||||
params: LanguageModelCallOptions,
|
||||
): {
|
||||
transform: TransformStream<LanguageModelStreamPart, LanguageModelStreamPart>
|
||||
getGeneratedText: () => string
|
||||
} => {
|
||||
let generatedText = ""
|
||||
|
||||
const transform = new TransformStream<
|
||||
LanguageModelStreamPart,
|
||||
LanguageModelStreamPart
|
||||
>({
|
||||
transform(chunk, controller) {
|
||||
if (chunk.type === "text-delta") {
|
||||
generatedText += chunk.delta
|
||||
}
|
||||
controller.enqueue(chunk)
|
||||
},
|
||||
flush: async () => {
|
||||
const userMessage = getLastUserMessage(params)
|
||||
if (ctx.addMemory === "always" && userMessage && userMessage.trim()) {
|
||||
saveMemoryAfterResponse(
|
||||
ctx.client,
|
||||
ctx.containerTag,
|
||||
ctx.conversationId,
|
||||
generatedText,
|
||||
params,
|
||||
ctx.logger,
|
||||
ctx.apiKey,
|
||||
ctx.normalizedBaseUrl,
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
transform,
|
||||
getGeneratedText: () => generatedText,
|
||||
}
|
||||
}
|
||||
|
||||
export { createLogger, type Logger, type OutputContentItem }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,25 @@
|
|||
import type { LanguageModelV2CallOptions, LanguageModelV2Message } from "@ai-sdk/provider"
|
||||
import type {
|
||||
LanguageModelV2,
|
||||
LanguageModelV2CallOptions,
|
||||
LanguageModelV2Message,
|
||||
LanguageModelV2StreamPart,
|
||||
LanguageModelV3,
|
||||
LanguageModelV3CallOptions,
|
||||
LanguageModelV3Message,
|
||||
LanguageModelV3StreamPart,
|
||||
} from "@ai-sdk/provider"
|
||||
|
||||
// Union types for dual SDK version support (V2 = SDK 5, V3 = SDK 6)
|
||||
export type LanguageModel = LanguageModelV2 | LanguageModelV3
|
||||
export type LanguageModelCallOptions =
|
||||
| LanguageModelV2CallOptions
|
||||
| LanguageModelV3CallOptions
|
||||
export type LanguageModelMessage =
|
||||
| LanguageModelV2Message
|
||||
| LanguageModelV3Message
|
||||
export type LanguageModelStreamPart =
|
||||
| LanguageModelV2StreamPart
|
||||
| LanguageModelV3StreamPart
|
||||
|
||||
export interface ProfileStructure {
|
||||
profile: {
|
||||
|
|
@ -58,20 +79,18 @@ export function convertProfileToMarkdown(data: ProfileMarkdownData): string {
|
|||
return sections.join("\n\n")
|
||||
}
|
||||
|
||||
export const getLastUserMessage = (params: LanguageModelV2CallOptions) => {
|
||||
export const getLastUserMessage = (params: LanguageModelCallOptions) => {
|
||||
const lastUserMessage = params.prompt
|
||||
.slice()
|
||||
.reverse()
|
||||
.find((prompt: LanguageModelV2Message) => prompt.role === "user")
|
||||
.find((prompt: LanguageModelMessage) => prompt.role === "user")
|
||||
const memories = lastUserMessage?.content
|
||||
.filter((content) => content.type === "text")
|
||||
.map((content) => content.text)
|
||||
.map((content) => (content as { type: "text"; text: string }).text)
|
||||
.join(" ")
|
||||
return memories
|
||||
}
|
||||
|
||||
|
||||
export const filterOutSupermemories = (content: string) => {
|
||||
return content.split("User Supermemories: ")[0]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue