diff --git a/README.md b/README.md index cac8433..52005ee 100644 --- a/README.md +++ b/README.md @@ -32,16 +32,16 @@ yarn add langbase ### Usage -You can [`generateText`](https://langbase.com/docs/langbase-sdk/generate-text) or [`streamText`](https://langbase.com/docs/langbase-sdk/stream-text) based on the type of a pipe. +You can [`langbase.pipe.run()`](https://langbase.com/docs/sdk/pipe/run) to generate or stream from a Pipe. -Check our [SDK documentation](https://langbase.com/docs/langbase-sdk/overview) for more details. +Check our [SDK documentation](https://langbase.com/docs/sdk) for more details. ### Example projects Check the following examples: -- [Node: Generate Text](https://github.com/LangbaseInc/langbase-sdk/blob/main/examples/everything/generate-text.ts) -- [Node: Stream Text](https://github.com/LangbaseInc/langbase-sdk/blob/main/examples/everything/stream-text.ts) +- [Node: Generate Text](https://github.com/LangbaseInc/langbase-sdk/blob/main/examples/nodejs/examples/pipes/pipe.run.ts) +- [Node: Stream Text](https://github.com/LangbaseInc/langbase-sdk/blob/main/examples/nodejs/examples/pipes/pipe.run.stream.ts) - [Next.js Example](https://github.com/LangbaseInc/langbase-sdk/tree/main/examples/nextjs) - TypeScript code - [React component](https://github.com/LangbaseInc/langbase-sdk/tree/main/examples/nextjs/components/langbase) to display the response @@ -52,69 +52,85 @@ Check the following examples: ## Node.js Examples -### Add a `.env` file with your Pipe API key +### Add a `.env` file with your LANGBASE API key ```bash # Add your Pipe API key here. -LANGBASE_PIPE_API_KEY="pipe_12345`" +LANGBASE_API_KEY="your-api-key" ``` --- -### Generate text [`generateText()`](https://langbase.com/docs/langbase-sdk/generate-text) +### Generate text [`langbase.pipe.run()`](https://langbase.com/docs/sdk/pipe/run) -For more check the API reference of [`generateText()`](https://langbase.com/docs/langbase-sdk/generate-text) +Set the `stream` to `false`. For more, check the API reference of [`langbase.pipe.run()`](https://langbase.com/docs/langbase-sdk/generate-text) ```ts import 'dotenv/config'; -import {Pipe} from 'langbase'; +import {Langbase} from 'langbase'; -// 1. Initiate the Pipe. -const pipe = new Pipe({ - // Make sure you have a .env file with any pipe you wanna use. - // As a demo we're using a pipe that has less wordy responses. - apiKey: process.env.LANGBASE_PIPE_API_KEY!, +// 1. Initiate the Langbase. +const langbase = new Langbase({ + // Make sure you have a .env file with LANGBASE_API_KEY. + apiKey: process.env.LANGBASE_API_KEY!, }); -// 3. Generate the text by asking a question. -const result = await pipe.generateText({ - messages: [{role: 'user', content: 'Who is an AI Engineer?'}], -}); +async function main() { + // 2. Run the pipe with a question. + const response = await langbase.pipe.run({ + stream: false, + name: 'summary' // pipe name to run + messages: [ + { + role: 'user', + content: 'Who is an AI Engineer?', + }, + ], + }); + + // 3. Print the response. + console.log('response: ', response); +} -// 4. Done: You got the generated completion. -console.log(result.completion); +main(); ``` --- -### Stream text [`streamText()`](https://langbase.com/docs/langbase-sdk/stream-text) +### Stream text [`langbase.pipe.run()`](https://langbase.com/docs/sdk/pipe/run) -For more check the API reference of [`streamText()`](https://langbase.com/docs/langbase-sdk/stream-text) +Set the `stream` to `true`. For more, check the API reference of [`langbase.pipe.run()`](https://langbase.com/docs/langbase-sdk/generate-text) ```ts import 'dotenv/config'; -import {Pipe} from 'langbase'; +import {getRunner, Langbase} from 'langbase'; -// 1. Initiate the Pipe. -const pipe = new Pipe({ - // Make sure you have a .env file with any pipe you wanna use. - // As a demo we're using a pipe that has less wordy responses. - apiKey: process.env.LANGBASE_PIPE_API_KEY!, +// 1. Initiate the Langbase. +const langbase = new Langbase({ + // Make sure you have a .env file with LANGBASE_API_KEY. + apiKey: process.env.LANGBASE_API_KEY!, }); -// 2. Generate a stream by asking a question -const stream = await pipe.streamText({ - messages: [{role: 'user', content: 'Who is an AI Engineer?'}], -}); +async function main() { + const userMsg = 'Who is an AI Engineer?'; -// 3. Print the stream -for await (const chunk of stream) { - // Streaming text part — a single word or several. - const textPart = chunk.choices[0]?.delta?.content || ''; + // 2. Run the pipe with a question. + const {stream, threadId, rawResponse} = await langbase.pipe.run({ + stream: true, + name: 'summary', // pipe name to run + messages: [{role: 'user', content: userMsg}], + }); - // Demo: Print the stream — you can use it however. - process.stdout.write(textPart); + // 3. Get the runner and listen to the content. + const runner = getRunner(stream); + + // 4. Print the response. + runner.on('content', content => { + process.stdout.write(content); + }); } + +main(); ``` -Check out [more examples in the docs](https://langbase.com/docs/langbase-sdk/examples) → +Check out [more examples in the docs](https://langbase.com/docs/sdk/examples) → diff --git a/examples/nextjs/app/langbase/pipe/generate-text/route.ts b/examples/nextjs/app/langbase/pipe/generate-text/route.ts deleted file mode 100644 index 2c0b959..0000000 --- a/examples/nextjs/app/langbase/pipe/generate-text/route.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Pipe} from 'langbase'; - -export async function POST(req: Request) { - // 0. Take out user prompt. - const {prompt} = await req.json(); - - // 1. Initiate the Pipe. - const myPipe = new Pipe({apiKey: process.env.LANGBASE_PIPE_LESS_WORDY!}); - - // 3. Generate the text by asking a question. - const result = await myPipe.generateText({ - // Add user question prompt here to generate completion. - messages: [{role: 'user', content: prompt}], - }); - - // 4. Done: You got the generated completion on result.completion. - return Response.json(result); -} diff --git a/examples/nextjs/app/langbase/pipe/stream-text/route.ts b/examples/nextjs/app/langbase/pipe/stream-text/route.ts deleted file mode 100644 index 336ebc7..0000000 --- a/examples/nextjs/app/langbase/pipe/stream-text/route.ts +++ /dev/null @@ -1,21 +0,0 @@ -// import {Pipe} from 'langbase'; -import {Pipe} from 'langbase'; - -import {NextRequest} from 'next/server'; - -export async function POST(req: NextRequest) { - const {prompt} = await req.json(); - - // 1. Initiate the Pipe. - const myPipe = new Pipe({ - apiKey: process.env.LANGBASE_PIPE_LESS_WORDY!, - }); - - // 2. Generate a stream by asking a question - const {stream} = await myPipe.streamText({ - messages: [{role: 'user', content: prompt}], - }); - - // 3. Done, return the stream in a readable stream format. - return new Response(stream.toReadableStream()); -} diff --git a/examples/nextjs/app/page.tsx b/examples/nextjs/app/page.tsx index 19e6fb6..f22f39b 100644 --- a/examples/nextjs/app/page.tsx +++ b/examples/nextjs/app/page.tsx @@ -1,7 +1,5 @@ -import GenerateTextExample from '@/components/langbase/generate-text'; import RunNonStreamExample from '@/components/langbase/run'; import RunStreamExample from '@/components/langbase/run-stream'; -import StreamTextExample from '@/components/langbase/stream-text'; export default function Home() { return ( @@ -17,8 +15,6 @@ export default function Home() { - - ); diff --git a/examples/nodejs/.env.example b/examples/nodejs/.env.example index ac71c56..dfb1f50 100644 --- a/examples/nodejs/.env.example +++ b/examples/nodejs/.env.example @@ -2,3 +2,5 @@ PIPE_LESS_WORDY="" LANGBASE_SDK_GENERATE_PIPE="" LANGBASE_SDK_CHAT_PIPE="" +LANGBASE_API_KEY="" +WEB_SEARCH_KEY="" diff --git a/examples/nodejs/examples/tools/web-search.ts b/examples/nodejs/examples/tools/web-search.ts new file mode 100644 index 0000000..5d90673 --- /dev/null +++ b/examples/nodejs/examples/tools/web-search.ts @@ -0,0 +1,17 @@ +import 'dotenv/config'; +import {Langbase} from 'langbase'; + +const langbase = new Langbase({ + apiKey: process.env.LANGBASE_API_KEY!, +}); + +async function main() { + const results = await langbase.tool.webSearch({ + query: 'AI Engineer', + apiKey: process.env.WEB_SEARCH_KEY, + }); + + console.log(results); +} + +main(); diff --git a/examples/nodejs/package.json b/examples/nodejs/package.json index 56f9a0f..5503f6a 100644 --- a/examples/nodejs/package.json +++ b/examples/nodejs/package.json @@ -27,7 +27,8 @@ "generate-text-chat-pipe": "npx tsx ./examples/pipes/generate-text-chat-pipe.ts", "stream-text": "npx tsx ./examples/pipes/stream-text.ts", "stream-text-generate-pipe": "npx tsx ./examples/pipes/stream-text-generate-pipe.ts", - "stream-text-chat-pipe": "npx tsx ./examples/pipes/stream-text-chat-pipe.ts" + "stream-text-chat-pipe": "npx tsx ./examples/pipes/stream-text-chat-pipe.ts", + "tools.web-search": "npx tsx ./examples/tools/web-search.ts" }, "keywords": [], "author": "Ahmad Awais (https://twitter.com/MrAhmadAwais)", diff --git a/packages/langbase/src/langbase/langbase.ts b/packages/langbase/src/langbase/langbase.ts index ada0f6b..8954f69 100644 --- a/packages/langbase/src/langbase/langbase.ts +++ b/packages/langbase/src/langbase/langbase.ts @@ -248,6 +248,18 @@ export interface LangbaseOptions { apiKey: string; } +export interface ToolWebSearchOptions { + query: string; + total_results?: number; + domains?: string[]; + apiKey?: string; +} + +export interface ToolWebSearchResponse { + url: string; + content: string; +} + export class Langbase { private request: Request; private apiKey: string; @@ -283,6 +295,12 @@ export class Langbase { }; }; + public tool: { + webSearch: ( + options: ToolWebSearchOptions, + ) => Promise; + }; + constructor(options?: LangbaseOptions) { const baseUrl = 'https://api.langbase.com'; this.apiKey = options?.apiKey ?? ''; @@ -311,6 +329,10 @@ export class Langbase { }, }, }; + + this.tool = { + webSearch: this.webSearch.bind(this), + }; } private async runPipe( @@ -526,4 +548,25 @@ export class Langbase { endpoint: `/v1/memory/${options.memoryName}/documents/${options.documentName}/embeddings/retry`, }); } + + /** + * Performs a web search using the Langbase API. + * + * @param options - Web search configuration options + * @param options.apiKey - Optional API key for web search authentication + * @returns Promise that resolves to an array of web search results + */ + private async webSearch( + options: ToolWebSearchOptions, + ): Promise { + return this.request.post({ + endpoint: '/v1/tools/web-search', + body: options, + headers: { + ...(options.apiKey && { + 'LB-WEB-SEARCH-KEY': options.apiKey, + }), + }, + }); + } } diff --git a/packages/langbase/src/pipes/pipes.ts b/packages/langbase/src/pipes/pipes.ts index 0edbe1c..31553a6 100644 --- a/packages/langbase/src/pipes/pipes.ts +++ b/packages/langbase/src/pipes/pipes.ts @@ -1,8 +1,7 @@ -import { Message, Role, ToolCall, Variable } from '@/langbase/langbase'; +import {Message, Role, ToolCall, Variable} from '@/langbase/langbase'; import {Request} from '../common/request'; import {Stream} from '../common/stream'; - export interface GenerateOptions { messages?: Message[]; variables?: Variable[]; @@ -84,6 +83,12 @@ export class Pipe { this.request = new Request({apiKey: options.apiKey, baseUrl}); } + /** + * @deprecated This method is deprecated and will be removed in a future version. + * + * Please use `langbase.pipe.run()` instead + * @see https://langbase.com/docs/sdk/pipe/run + */ async generateText(options: GenerateOptions): Promise { return this.request.post({ endpoint: options.chat ? '/beta/chat' : '/beta/generate', @@ -91,6 +96,12 @@ export class Pipe { }); } + /** + * @deprecated This method is deprecated and will be removed in a future version. + * + * Please use `langbase.pipe.run()` instead + * @see https://langbase.com/docs/sdk/pipe/run + */ async streamText(options: StreamOptions): Promise { return this.request.post({ endpoint: options.chat ? '/beta/chat' : '/beta/generate',