diff --git a/examples/nodejs/examples/pipes/memory.create.ts b/examples/nodejs/examples/memory/memory.create.ts similarity index 100% rename from examples/nodejs/examples/pipes/memory.create.ts rename to examples/nodejs/examples/memory/memory.create.ts diff --git a/examples/nodejs/examples/memory/memory.delete.ts b/examples/nodejs/examples/memory/memory.delete.ts new file mode 100644 index 0000000..ce82e04 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.delete.ts @@ -0,0 +1,16 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const response = await memory.delete({ + name: 'memory-sdk', + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/examples/memory/memory.docs.delete.ts b/examples/nodejs/examples/memory/memory.docs.delete.ts new file mode 100644 index 0000000..6f0d664 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.docs.delete.ts @@ -0,0 +1,17 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const response = await memory.deleteDoc({ + memoryName: 'memory-sdk', + documentName: 'readme.md', + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/examples/memory/memory.docs.list.ts b/examples/nodejs/examples/memory/memory.docs.list.ts new file mode 100644 index 0000000..0917887 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.docs.list.ts @@ -0,0 +1,16 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const response = await memory.listDocs({ + memoryName: 'memory-sdk' + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/examples/memory/memory.docs.retry-embed.ts b/examples/nodejs/examples/memory/memory.docs.retry-embed.ts new file mode 100644 index 0000000..9dccaf3 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.docs.retry-embed.ts @@ -0,0 +1,17 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const response = await memory.retryDocEmbed({ + memoryName: 'memory-sdk', + documentName: 'memory.upload.doc.ts', + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/examples/memory/memory.docs.upload.ts b/examples/nodejs/examples/memory/memory.docs.upload.ts new file mode 100644 index 0000000..3b30448 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.docs.upload.ts @@ -0,0 +1,33 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; +import fs from 'fs'; +import path from 'path'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const src = path.join( + process.cwd(), + 'examples', + 'memory', + 'memory.upload.doc.ts', + ); + const file = fs.readFileSync(src); + + const response = await memory.uploadDoc({ + file, + memoryName: 'memory-sdk', + fileName: 'memory.upload.doc.ts', + contentType: 'text/plain', + meta: { + extension: 'ts', + description: 'This is a test file', + }, + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/examples/pipes/memory.list.ts b/examples/nodejs/examples/memory/memory.list.ts similarity index 100% rename from examples/nodejs/examples/pipes/memory.list.ts rename to examples/nodejs/examples/memory/memory.list.ts diff --git a/examples/nodejs/examples/memory/memory.retrieve.ts b/examples/nodejs/examples/memory/memory.retrieve.ts new file mode 100644 index 0000000..8eb61e6 --- /dev/null +++ b/examples/nodejs/examples/memory/memory.retrieve.ts @@ -0,0 +1,22 @@ +import 'dotenv/config'; +import {Memory} from 'langbase'; + +const memory = new Memory({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const response = await memory.retrieve({ + memory: [ + { + name: 'langbase-docs', + }, + ], + query: 'What are pipes in Langbase?', + topK: 2, + }); + + console.log(response); +} + +main(); diff --git a/examples/nodejs/package.json b/examples/nodejs/package.json index ac9d5b7..fab3a81 100644 --- a/examples/nodejs/package.json +++ b/examples/nodejs/package.json @@ -8,8 +8,14 @@ "scripts": { "generate-text": "npx tsx ./examples/pipes/generate-text.ts", "pipe.create": "npx tsx ./examples/pipes/pipe.create.ts", - "memory.create": "npx tsx ./examples/pipes/memory.create.ts", - "memory.list": "npx tsx ./examples/pipes/memory.list.ts", + "memory.create": "npx tsx ./examples/memory/memory.create.ts", + "memory.list": "npx tsx ./examples/memory/memory.list.ts", + "memory.delete": "npx tsx ./examples/memory/memory.delete.ts", + "memory.retrieve": "npx tsx ./examples/memory/memory.retrieve.ts", + "memory.docs.list": "npx tsx ./examples/memory/memory.docs.list.ts", + "memory.docs.delete": "npx tsx ./examples/memory/memory.docs.delete.ts", + "memory.docs.upload": "npx tsx ./examples/memory/memory.docs.upload.ts", + "memory.docs.retry-embed": "npx tsx ./examples/memory/memory.docs.retry-embed.ts", "pipe.update": "npx tsx ./examples/pipes/pipe.update.ts", "pipe.list": "npx tsx ./examples/pipes/pipe.list.ts", "pipe.run": "npx tsx ./examples/pipes/pipe.run.ts", diff --git a/packages/langbase/src/memory/memory.ts b/packages/langbase/src/memory/memory.ts index 571f7d8..fb98c2c 100644 --- a/packages/langbase/src/memory/memory.ts +++ b/packages/langbase/src/memory/memory.ts @@ -16,17 +16,98 @@ export interface MemoryCreateOptions { description?: string; } +export interface MemoryDeleteOptions { + name: string; +} + +export interface MemoryRetrieveOptions { + query: string; + memory: { + name: string; + }[]; + topK?: number; +} + +export interface MemoryListDocOptions { + memoryName: string; +} + +export interface MemoryDeleteDocOptions { + memoryName: string; + documentName: string; +} + +export interface MemoryUploadDocOptions { + memoryName: string; + fileName: string; + meta?: Record; + file: Buffer | File | FormData | ReadableStream; + contentType: + | 'application/pdf' + | 'text/plain' + | 'text/markdown' + | 'text/csv'; +} + +export interface MemoryRetryDocEmbedOptions { + memoryName: string; + documentName: string; +} + export interface MemoryCreateResponse extends MemoryBaseResponse {} export interface MemoryListResponse extends MemoryBaseResponse {} +export interface BaseDeleteResponse { + success: boolean; +} + +export interface MemoryDeleteResponse extends BaseDeleteResponse {} +export interface MemoryDeleteDocResponse extends BaseDeleteResponse {} +export interface MemoryRetryDocEmbedResponse extends BaseDeleteResponse {} + +export interface MemoryRetrieveResponse { + text: string; + similarity: number; + meta: Record; +} + +export interface MemoryListDocResponse { + name: string; + status: 'queued' | 'in_progress' | 'completed' | 'failed'; + status_message: string | null; + metadata: { + size: number; + type: + | 'application/pdf' + | 'text/plain' + | 'text/markdown' + | 'text/csv' + | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + | 'application/vnd.ms-excel'; + }; + enabled: boolean; + chunk_size: number; + chunk_overlap: number; + owner_login: string; +} export class Memory { private request: Request; + private apiKey: string; constructor(options: MemoryOptions) { const baseUrl = 'https://api.langbase.com'; + this.apiKey = options.apiKey; this.request = new Request({apiKey: options.apiKey, baseUrl}); } + /** + * Creates a new memory on Langbase. + * + * @param {MemoryCreateOptions} options - The options to create the memory instance. + * @param {string} options.name - The name of the memory. + * @param {string} options.description - The description of the memory. + * @returns {Promise} A promise that resolves to the response of the memory creation. + */ async create(options: MemoryCreateOptions): Promise { return this.request.post({ endpoint: '/v1/memory', @@ -34,9 +115,130 @@ export class Memory { }); } + /** + * Retrieves a list of all memories on Langbase. + * + * @returns {Promise} A promise that resolves to an array of memory list responses. + */ async list(): Promise { return this.request.get({ endpoint: '/v1/memory', }); } + + /** + * Deletes a memory on Langbase. + * + * @param {MemoryDeleteOptions} options - The options for deleting the memory resource. + * @param {string} options.name - The name of the memory to delete. + * @returns {Promise} A promise that resolves to the response of the delete operation. + */ + async delete(options: MemoryDeleteOptions): Promise { + return this.request.delete({ + endpoint: `/v1/memory/${options.name}`, + }); + } + + /** + * Retrieves similar text from the memory. + * + * @param {MemoryRetrieveOptions} options - The options to use for retrieving memory data. + * @param {string} options.query - The query text to search for. + * @param {object[]} options.memory - The memory to search in. + * @param {number} [options.topK] - The number of similar texts to retrieve. + * @returns A promise that resolves to an array of `MemoryRetrieveResponse` objects. + */ + async retrieve( + options: MemoryRetrieveOptions, + ): Promise { + return this.request.post({ + endpoint: '/v1/memory/retrieve', + body: options, + }); + } + + /** + * Retrieves a list of documents inside a memory. + * + * @param {MemoryListDocOptions} options - The options for listing documents, including the memory name. + * @param {string} options.memoryName - The name of the memory to list documents from. + * @returns A promise that resolves to an array of `MemoryListDocResponse` objects. + */ + async listDocs( + options: MemoryListDocOptions, + ): Promise { + return this.request.get({ + endpoint: `/v1/memory/${options.memoryName}/documents`, + }); + } + + /** + * Deletes a document from a memory. + * + * @param {MemoryDeleteDocOptions} options - The options for deleting the document. + * @param {string} options.memoryName - The name of the memory to delete the document from. + * @param {string} options.documentName - The name of the document to delete. + * @returns A promise that resolves to a `MemoryDeleteDocResponse` indicating the result of the delete operation. + */ + async deleteDoc( + options: MemoryDeleteDocOptions, + ): Promise { + return this.request.delete({ + endpoint: `/v1/memory/${options.memoryName}/documents/${options.documentName}`, + }); + } + + /** + * Uploads a document to the memory. + * + * @param {MemoryUploadDocOptions} options - The options for uploading the document. + * @param {string} options.memoryName - The name of the memory to upload the document to. + * @param {string} options.fileName - The name of the file being uploaded. + * @param {object} [options.meta] - Optional metadata associated with the document. + * @param {string} options.contentType - The MIME type of the file being uploaded. + * @param {Blob | Buffer} options.file - The file content to be uploaded. + * @returns {Promise} The response from the upload request. + * @throws Will throw an error if the upload fails. + */ + async uploadDoc(options: MemoryUploadDocOptions): Promise { + try { + const response = (await this.request.post({ + endpoint: `/v1/memory/documents`, + body: { + memoryName: options.memoryName, + fileName: options.fileName, + meta: options.meta, + }, + })) as unknown as {signedUrl: string}; + + const uploadUrl = response.signedUrl; + + return await fetch(uploadUrl, { + method: 'PUT', + headers: { + Authorization: `Bearer ${this.apiKey}`, + 'Content-Type': options.contentType, + }, + body: options.file, + }); + } catch (error) { + throw error; + } + } + + /** + * Retries the embedding process for a specific document in memory. + * + * @param options - The options required to retry the document embedding. + * @param options.memoryName - The name of the memory containing the document. + * @param options.documentName - The name of the document to retry embedding for. + * @returns A promise that resolves to the response of the retry operation. + */ + async retryDocEmbed( + options: MemoryRetryDocEmbedOptions, + ): Promise { + return this.request.get({ + endpoint: `/v1/memory/${options.memoryName}/documents/${options.documentName}/embeddings/retry`, + }); + } }