From 24eeb798f95f1f7757722abe2ea62fba56f6e05f Mon Sep 17 00:00:00 2001 From: Narcisse Date: Fri, 20 Sep 2024 12:59:58 +0100 Subject: [PATCH] chore:integration tests for jigsawstack tools --- packages/jigsawstack/src/integration.test.ts | 98 +++++++++++-------- .../jigsawstack/src/jigsawstack-client.ts | 55 ++++++++++- packages/jigsawstack/src/tool.test.ts | 57 +++++++++++ 3 files changed, 167 insertions(+), 43 deletions(-) create mode 100644 packages/jigsawstack/src/tool.test.ts diff --git a/packages/jigsawstack/src/integration.test.ts b/packages/jigsawstack/src/integration.test.ts index 6a7cace..3121856 100644 --- a/packages/jigsawstack/src/integration.test.ts +++ b/packages/jigsawstack/src/integration.test.ts @@ -1,57 +1,71 @@ // eslint-disable-next-line simple-import-sort/imports - +import { openai } from '@ai-sdk/openai' +import { generateText } from 'ai' import { expect, test } from 'vitest' +import { createAISDKTools } from '../../ai-sdk' +import { JigsawStackClient } from './jigsawstack-client' -import { type jigsawstack,JigsawStackClient } from './jigsawstack-client' +// Do ensure to set your JIGSAWSTACK_API_KEY environment variable. -const jigsaw = new JigsawStackClient() +const jigsaw = new JigsawStackClient({ timeoutMs: 30_000 }) -test.skip('should run successfully and return the search result', async () => { - const params: jigsawstack.SearchParams = { - query: 'The leaning tower of pisa', - ai_overview: true, - spell_check: true - } - const result = await jigsaw.aiSearch(params) - expect(result).toBeTruthy() - expect(result.success).toBe(true) +test.skip('should run successfully and return search result', async () => { + const { toolResults } = await generateText({ + model: openai('gpt-4o-mini'), + tools: createAISDKTools(jigsaw), + toolChoice: 'required', + prompt: 'Tell me about "Santorini"' + }) + + // console.log(toolResults, 'toolResults') + expect(toolResults[0]).toBeTruthy() }) -test.skip('should run successfully and return the valid sql result', async () => { - const params: jigsawstack.TextToSqlParams = { - sql_schema: - "CREATE TABLE Transactions (transaction_id INT PRIMARY KEY, user_id INT NOT NULL,total_amount DECIMAL(10, 2 NOT NULL, transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(20) DEFAULT 'pending',FOREIGN KEY(user_id) REFERENCES Users(user_id))", +test.skip('should scrape url successfully and return result', async () => { + const { toolResults } = await generateText({ + model: openai('gpt-4o-mini'), + tools: createAISDKTools(jigsaw), + toolChoice: 'required', + prompt: 'Scrape https://jigsawstack.com and tell me their title' + }) + + // console.log(toolResults[0], 'toolResults') + expect(toolResults[0]).toBeTruthy() +}) + +test.skip('should perform vision based OCR and return result', async () => { + const { toolResults } = await generateText({ + model: openai('gpt-4o-mini'), + tools: createAISDKTools(jigsaw), + toolChoice: 'required', prompt: - 'Generate a query to get transactions that amount exceed 10000 and sort by when created' - } - - const result = await jigsaw.textToSql(params) - expect(result).toBeTruthy() - expect(result.success).toBe(true) -}) - -test.skip('should return result.success is true for successful vocr', async () => { - const result = await jigsaw.vocr({ - prompt: 'Describe the image in detail', - url: 'https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z' + 'Tell me about this image : https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z' }) - expect(result.success).toBe(true) + // console.log(toolResults[0], 'toolResults') + expect(toolResults[0]).toBeTruthy() }) -test('should run successfully and return the transcribe result', async () => { - const data = await jigsaw.speechToText({ - url: 'https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Video%201737458382653833217.mp4?t=2024-03-22T09%3A50%3A49.894' +test.skip('should perform speech to text and return result', async () => { + const { toolResults } = await generateText({ + model: openai('gpt-4o-mini'), + tools: createAISDKTools(jigsaw), + toolChoice: 'required', + prompt: + 'Get the transcription from this video url : https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Video%201737458382653833217.mp4?t=2024-03-22T09%3A50%3A49.894Z' }) - expect(data).toBeTruthy() - expect(data.success).toBe(true) + // console.log(toolResults[0], 'toolResults') + expect(toolResults[0]).toBeTruthy() }) -test.skip('should run successfully and return scrape result', async () => { - const params: jigsawstack.ScrapeParams = { - url: 'https://jigsawstack.com/pricing', - element_prompts: ['Pro Plan'] - } - const result = await jigsaw.aiScrape(params) - expect(result).toBeTruthy() - expect(result.success).toBe(true) +test('should perform text to sql and return result', async () => { + const prompt = ` + Generate a query to get transactions that amount exceed 10000 and sort by when created. Given this schema: + "CREATE TABLE Transactions (transaction_id INT PRIMARY KEY, user_id INT NOT NULL,total_amount DECIMAL(10, 2 NOT NULL, transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(20) DEFAULT 'pending',FOREIGN KEY(user_id) REFERENCES Users(user_id))"` + const { toolResults } = await generateText({ + model: openai('gpt-4o-mini'), + tools: createAISDKTools(jigsaw), + toolChoice: 'required', + prompt + }) + expect(toolResults[0]).toBeTruthy() }) diff --git a/packages/jigsawstack/src/jigsawstack-client.ts b/packages/jigsawstack/src/jigsawstack-client.ts index fd0d7ff..003e041 100644 --- a/packages/jigsawstack/src/jigsawstack-client.ts +++ b/packages/jigsawstack/src/jigsawstack-client.ts @@ -1,5 +1,6 @@ -import { AIFunctionsProvider, assert, getEnv } from '@agentic/core' +import { aiFunction,AIFunctionsProvider, assert, getEnv } from '@agentic/core' import ky, { type KyInstance } from 'ky' +import { z } from 'zod' export namespace jigsawstack { export interface BaseResponse { @@ -154,6 +155,14 @@ export class JigsawStackClient extends AIFunctionsProvider { }) } + @aiFunction({ + name: 'jigsawstack_ai_search', + description: + 'Perform web searches and retrieve high-quality results of the given query', + inputSchema: z.object({ + query: z.string().describe('The search query') + }) + }) async aiSearch(params: jigsawstack.SearchParams) { return this.ky .get('web/search', { @@ -164,6 +173,18 @@ export class JigsawStackClient extends AIFunctionsProvider { .json() } + @aiFunction({ + name: 'jigsawstack_ai_scrape', + description: 'Scrape any website', + inputSchema: z.object({ + url: z.string().describe('The url to scrape its content'), + element_prompts: z + .array(z.string()) + .describe( + 'The items to scrape (retrieve) from the given url. eg. Page title, price, etc' + ) + }) + }) async aiScrape(params: jigsawstack.ScrapeParams) { return this.ky .post('ai/scrape', { @@ -174,6 +195,18 @@ export class JigsawStackClient extends AIFunctionsProvider { .json() } + @aiFunction({ + name: 'jigsawstack_vocr', + description: + 'Recognise, describe and retrieve data within an image with great accuracy.', + inputSchema: z.object({ + url: z.string().describe('The image url to OCR'), + prompt: z + .string() + .default('Describe the image in detail.') + .describe('What you want to know or retrieve from the image') + }) + }) async vocr(params: jigsawstack.VOCRParams) { return this.ky .post('vocr', { @@ -184,6 +217,18 @@ export class JigsawStackClient extends AIFunctionsProvider { .json() } + @aiFunction({ + name: 'jigsawstack_text_to_sql', + description: 'Generate semantically correct SQL queries from text.', + inputSchema: z.object({ + prompt: z + .string() + .describe('The text that will be translated to an SQL query.'), + sql_schema: z + .string() + .describe('The valid sql schema where the query will be run') + }) + }) async textToSql( params: jigsawstack.TextToSqlParams ): Promise { @@ -196,6 +241,14 @@ export class JigsawStackClient extends AIFunctionsProvider { .json() } + @aiFunction({ + name: 'jigsawstack_speech_to_text', + description: + 'Convert audio/video files into accurate text transcriptions instantly.', + inputSchema: z.object({ + url: z.string().describe('The audio or video url') + }) + }) async speechToText( params: jigsawstack.SpeechToTextParams ): Promise { diff --git a/packages/jigsawstack/src/tool.test.ts b/packages/jigsawstack/src/tool.test.ts new file mode 100644 index 0000000..d3a2bbe --- /dev/null +++ b/packages/jigsawstack/src/tool.test.ts @@ -0,0 +1,57 @@ +// eslint-disable-next-line simple-import-sort/imports + +import { expect, test } from 'vitest' + +import { type jigsawstack, JigsawStackClient } from './jigsawstack-client' + +const jigsaw = new JigsawStackClient() + +test.skip('should run successfully and return the search result', async () => { + const params: jigsawstack.SearchParams = { + query: 'The leaning tower of pisa', + ai_overview: true, + spell_check: true + } + const result = await jigsaw.aiSearch(params) + expect(result).toBeTruthy() + expect(result.success).toBe(true) +}) + +test.skip('should run successfully and return the valid sql result', async () => { + const params: jigsawstack.TextToSqlParams = { + sql_schema: + "CREATE TABLE Transactions (transaction_id INT PRIMARY KEY, user_id INT NOT NULL,total_amount DECIMAL(10, 2 NOT NULL, transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(20) DEFAULT 'pending',FOREIGN KEY(user_id) REFERENCES Users(user_id))", + prompt: + 'Generate a query to get transactions that amount exceed 10000 and sort by when created' + } + + const result = await jigsaw.textToSql(params) + expect(result).toBeTruthy() + expect(result.success).toBe(true) +}) + +test.skip('should return result.success is true for successful vocr', async () => { + const result = await jigsaw.vocr({ + prompt: 'Describe the image in detail', + url: 'https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Collabo%201080x842.jpg?t=2024-03-22T09%3A22%3A48.442Z' + }) + expect(result.success).toBe(true) +}) + +test('should run successfully and return the transcribe result', async () => { + const data = await jigsaw.speechToText({ + url: 'https://rogilvkqloanxtvjfrkm.supabase.co/storage/v1/object/public/demo/Video%201737458382653833217.mp4?t=2024-03-22T09%3A50%3A49.894' + }) + expect(data).toBeTruthy() + expect(data.success).toBe(true) +}) + +test.skip('should run successfully and return scrape result', async () => { + const params: jigsawstack.ScrapeParams = { + url: 'https://jigsawstack.com/pricing', + element_prompts: ['Pro Plan'] + } + const result = await jigsaw.aiScrape(params) + expect(result).toBeTruthy() + expect(result.success).toBe(true) +})