diff --git a/examples/indexes.ts b/examples/indexes.ts new file mode 100644 index 0000000..8f0e649 --- /dev/null +++ b/examples/indexes.ts @@ -0,0 +1,73 @@ +import Client from '../src'; +import { Document } from '../src/types'; + +const client = new Client(); + +(async () => { + const index = await client.indexes.create('support-tickets'); + + + const tickets = [ + { + title: 'Issue with my account', + description: 'I cannot log in to my account', + status: 'open', + id: '1', + }, + { + title: 'Payment issue', + description: 'I cannot pay for my subscription', + status: 'open', + id: '2', + }, + { + title: 'Feature request', + description: 'I would like to request a new feature', + status: 'closed', + id: '3', + }, + { + title: 'Slow response time', + description: 'The response time for queries is too slow', + status: 'open', + id: '4', + }, + { + title: 'Data sync error', + description: 'There is an error syncing data across devices', + status: 'open', + id: '5', + }, + { + title: 'App crash on launch', + description: 'The app crashes every time I try to launch it', + status: 'open', + id: '6', + }, + ]; + // Add each ticket to the index. Add status to metadata so we can filter by it later. + for (const ticket of tickets) { + let doc: Document = { + content: ticket.title + ' ' + ticket.description, + metadata: { + "status": ticket.status, + } + } + await client.indexes.add(index, doc); + } + + const query = 'Issue with my account'; + const results = await client.indexes.retrieve(index, query, 1, null); + + console.log(results[0].content); + // 'Issue with my account I cannot log in to my account' + console.log(results[0].metadata); + // { status: 'open', id: '1' } + + let open_results = await client.indexes.retrieve(index, query, 1, [{ key: 'status', operation: '=', value: 'open' }]); + + console.log(open_results[0].content); + + // 'Issue with my account I cannot log in to my account' +})(); + diff --git a/examples/tracing.ts b/examples/tracing.ts index 1b4b7e4..11ed5aa 100644 --- a/examples/tracing.ts +++ b/examples/tracing.ts @@ -1,6 +1,6 @@ -import Client, { Span, fn } from "../src"; // import Client, { Span, fn } from "opperai"; import * as uuid from "uuid"; import { z } from "zod"; +import Client, { Span, fn } from "../src"; // import Client, { Span, fn } from "opperai"; // Define the input and output schemas with zod. const TranslationResultSchema = z.object({ @@ -17,6 +17,7 @@ const HappyTranslationResultSchema = z.object({ text: z.string(), }); +// Your API key will be loaded from the environment variable OPPER_API_KEY if not provided const client = new Client(); // Define the function using the fn decorator. This will create an opper function diff --git a/package.json b/package.json index 454440c..9224880 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opperai", - "version": "0.5.0", + "version": "0.5.1", "description": "Typescript SDK for the Opper API", "main": "dist/index.js", "types": "dist/index.js", diff --git a/src/fn.ts b/src/fn.ts index 618da16..40fda72 100644 --- a/src/fn.ts +++ b/src/fn.ts @@ -17,6 +17,29 @@ interface OpperOptions { out_schema?: Record; } +/** + * Decorator function that creates an opper function from an input and output schema. + * @param options - OpperOptions for the function. + * @param inputSchema - The input zod schema for the function. + * @param outputSchema - The output zod schema for the function. + * @returns A function that takes an input and returns a promise of the output. + * + * @example + * ```ts + * // Define the input and output schemas with zod. + * const TranslationResultSchema = z.object({ + * translation: z.string(), + * sentiment: z.string(), + * }); + * + * // Create an opper function. + * const translateAndAnalyze = fn({ path: 'translate-and-analyze', description: 'Translate text and analyze sentiment.' }, TranslationResultSchema, TranslationResultSchema); + * + * // Use the function. + * const result = await translateAndAnalyze({ text: 'Hello, world!' }); + * console.log(result); + * ``` + */ export default function fn, I extends z.ZodType>( options: OpperOptions, inputSchema: I, diff --git a/src/functions.ts b/src/functions.ts index cf59dc3..2979b10 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -6,7 +6,6 @@ import { APIError, OpperError } from "./errors"; class Functions extends APIResource { /** * This method is used to initiate a chat with the OpperAI API. - * It sends a POST request to the chat endpoint with the provided path and message. * The response is a promise that resolves to an object with the message and context. * @param path - The path to the chat endpoint. * @param message - The message to be sent. @@ -23,6 +22,13 @@ class Functions extends APIResource { return (await response.json()) as OpperAIChatResponse; } + /** + * Updates a function in the OpperAI API. + * @param f - The function to be updated. + * @returns A promise that resolves to the updated function. + * @throws {APIError} If the response status is not 200. + * @throws {OpperError} If the function id is not provided. + */ public async update(f: AIFunction): Promise { if (!f.id) { throw new OpperError("Function id is required"); @@ -37,6 +43,14 @@ class Functions extends APIResource { return f; } + /** + * Creates a function in the OpperAI API. + * @param f - The function to be created. + * @param update - Whether to update the function if it already exists. + * @returns A promise that resolves to the created function. + * @throws {APIError} If the response status is not 200. + * @throws {OpperError} If the function already exists and update is false. + */ public async create(f: AIFunction, update: boolean = false): Promise { try { const response = await this.doGet(this.calcURLGetFunctionByPath(f.path)); diff --git a/src/indexes.ts b/src/indexes.ts index 24082cd..5f2a4f7 100644 --- a/src/indexes.ts +++ b/src/indexes.ts @@ -19,6 +19,12 @@ class Indexes extends APIResource { return indexes; } + /** + * Retrieves an index by name from the OpperAI API. + * @param name The name of the index to retrieve. + * @returns A promise that resolves to the index with the given name, or null if no index with the given name exists. + * @throws {APIError} If the response status is not 200. + */ public async get(name: string): Promise { const list = await this.list(); @@ -30,6 +36,12 @@ class Indexes extends APIResource { return index; } + /** + * Creates an index in the OpperAI API. + * @param name The name of the index to create. + * @returns A promise that resolves to the created index. + * @throws {APIError} If the response status is not 200. + */ public async create(name: string): Promise { const response = await this.doPost(this.calcURLIndexes(), JSON.stringify({ name: name })); @@ -38,19 +50,47 @@ class Indexes extends APIResource { return data; } + /** + * Deletes an index + * @param id The id of the index to delete. + * @returns A promise that resolves to void. + * @throws {APIError} If the response status is not 200. + */ public async delete(id: number): Promise { await this.doDelete(this.calcURLIndex(id)); } + /** + * Adds a document to an index. + * @param index The index to add the document to. + * @param document The document to add to the index. + * @throws {APIError} If the response status is not 200. + * + * @example + * ```ts + * const index = await client.indexes.create('support-tickets'); + * const document = { title: 'My first support ticket', content: 'This is my first support ticket.' }; + * await client.indexes.add(index, document); + * ``` + */ public async add(index: Index, document: Document): Promise { await this.doPost(this.calcURLAddIndex(index.id), JSON.stringify(document)); } + /** + * Retrieves the most relevant documents from an index based on semantic similarity to a query. + * @param index The index to retrieve documents from. + * @param query The query to retrieve documents for. + * @param k The maximum number of documents to retrieve. + * @param filters The filters to apply to the documents in the index. + * @returns The most relevant documents from the index + * @throws {APIError} If the response status is not 200. + */ public async retrieve( index: Index, query: string, k: number, - filters: Filter[] + filters: Filter[] | null ): Promise { const response = await this.doPost( this.calcURLQueryIndex(index.id),